From b4fa2d90491066ac834d18be5517de473da0ac05 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 22 Dec 2018 16:51:24 +0100 Subject: [PATCH 001/278] WIP --- osu.Game.Tests/Visual/TestCaseUserPanel.cs | 1 + osu.Game.Tests/Visual/TestCaseUserProfile.cs | 15 +- .../Graphics/Containers/OsuHoverContainer.cs | 3 +- osu.Game/Graphics/OsuColour.cs | 10 + .../Overlays/Profile/Header/SupporterIcon.cs | 82 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 1089 +++++++++++++---- osu.Game/Overlays/UserProfileOverlay.cs | 6 +- osu.Game/Users/User.cs | 21 + osu.Game/Users/UserPanel.cs | 4 +- osu.Game/Users/UserStatistics.cs | 18 + osu.sln.DotSettings | 1 + 11 files changed, 981 insertions(+), 269 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserPanel.cs b/osu.Game.Tests/Visual/TestCaseUserPanel.cs index a53af247f3..81b7465d47 100644 --- a/osu.Game.Tests/Visual/TestCaseUserPanel.cs +++ b/osu.Game.Tests/Visual/TestCaseUserPanel.cs @@ -38,6 +38,7 @@ namespace osu.Game.Tests.Visual Country = new Country { FlagName = @"AU" }, CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg", IsSupporter = true, + SupportLevel = 3, }) { Width = 300 }, }, }); diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index cb281d045b..ce41bc22ff 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Overlays; @@ -27,7 +28,9 @@ namespace osu.Game.Tests.Visual typeof(UserProfileOverlay), typeof(RankGraph), typeof(LineGraph), - typeof(BadgeContainer) + typeof(BadgeContainer), + typeof(SectionsContainer<>), + typeof(SupporterIcon) }; public TestCaseUserProfile() @@ -58,6 +61,11 @@ namespace osu.Game.Tests.Visual { Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, PP = 4567.89m, + Level = new UserStatistics.LevelInfo + { + Current = 727, + Progress = 69, + } }, RankHistory = new User.RankHistoryData { @@ -72,7 +80,10 @@ namespace osu.Game.Tests.Visual Description = "Outstanding help by being a voluntary test subject.", ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" } - } + }, + Title = "osu!volunteer", + Colour = "ff0000", + Achievements = new User.UserAchievement[0], }, false)); checkSupporterTag(false); diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index af804735a8..418ccac290 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -33,7 +33,8 @@ namespace osu.Game.Graphics.Containers [BackgroundDependencyLoader] private void load(OsuColour colours) { - HoverColour = colours.Yellow; + if(HoverColour == default) + HoverColour = colours.Yellow; } protected override void LoadComplete() diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index fc627fa501..b069f2bf0e 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -92,5 +92,15 @@ namespace osu.Game.Graphics public readonly Color4 ChatBlue = FromHex(@"17292e"); public readonly Color4 ContextMenuGray = FromHex(@"223034"); + + public readonly Color4 CommunityUserGreenLight = FromHex(@"deff87"); + public readonly Color4 CommunityUserGreen = FromHex(@"05ffa2"); + public readonly Color4 CommunityUserGreenDark = FromHex(@"a6cc00"); + public readonly Color4 CommunityUserGrayGreenLighter = FromHex(@"9ebab1"); + public readonly Color4 CommunityUserGrayGreenLight = FromHex(@"77998e"); + public readonly Color4 CommunityUserGrayGreen = FromHex(@"4e7466"); + public readonly Color4 CommunityUserGrayGreenDark = FromHex(@"33413c"); + public readonly Color4 CommunityUserGrayGreenDarker = FromHex(@"2c3532"); + public readonly Color4 CommunityUserGrayGreenDarkest = FromHex(@"1e2422"); } } diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs index 1325ea4e9a..8b33a60d37 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osuTK; namespace osu.Game.Overlays.Profile.Header @@ -15,50 +14,73 @@ namespace osu.Game.Overlays.Profile.Header public class SupporterIcon : CircularContainer, IHasTooltip { private readonly Box background; + private readonly FillFlowContainer iconContainer; public string TooltipText => "osu!supporter"; + public int SupporterLevel + { + set + { + if (value == 0) + { + Hide(); + } + else + { + Show(); + iconContainer.Clear(); + for (int i = 0; i < value; i++) + { + iconContainer.Add(new SpriteIcon + { + Width = 12, + RelativeSizeAxes = Axes.Y, + Icon = FontAwesome.fa_heart, + }); + } + } + } + } + public SupporterIcon() { Masking = true; + AutoSizeAxes = Axes.X; + Hide(); + Children = new Drawable[] { - new Box { RelativeSizeAxes = Axes.Both }, - new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.8f), - Masking = true, - Children = new Drawable[] - { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Triangles - { - TriangleScale = 0.2f, - ColourLight = OsuColour.FromHex(@"ff7db7"), - ColourDark = OsuColour.FromHex(@"de5b95"), - RelativeSizeAxes = Axes.Both, - Velocity = 0.3f, - }, - } - }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.fa_heart, - Scale = new Vector2(0.45f), - } + background = new Box { RelativeSizeAxes = Axes.Both }, + iconContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Height = 0.6f, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } }; } + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + bool invalid = base.Invalidate(invalidation, source, shallPropagate); + + if ((invalidation & Invalidation.DrawSize) != 0) + { + iconContainer.Padding = new MarginPadding { Horizontal = DrawHeight / 2 }; + } + + return invalid; + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { background.Colour = colours.Pink; + iconContainer.Colour = colours.CommunityUserGrayGreenDark; } } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index a8075ec295..78f35b3da8 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -2,52 +2,91 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osuTK; -using osuTK.Graphics; +using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions; +using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Profile.Components; +using osu.Game.Online.Chat; using osu.Game.Overlays.Profile.Header; +using osu.Game.Scoring; using osu.Game.Users; +using osuTK; namespace osu.Game.Overlays.Profile { public class ProfileHeader : Container { - private readonly LinkFlowContainer infoTextLeft; - private readonly LinkFlowContainer infoTextRight; - private readonly FillFlowContainer scoreText, scoreNumberText; private readonly RankGraph rankGraph; public readonly SupporterIcon SupporterTag; private readonly Container coverContainer; - private readonly Sprite levelBadge; - private readonly SpriteText levelText; - private readonly GradeBadge gradeSSPlus, gradeSS, gradeSPlus, gradeS, gradeA; - private readonly Box colourBar; - private readonly DrawableFlag countryFlag; - private readonly BadgeContainer badgeContainer; + private readonly OsuSpriteText coverInfoText; + private readonly CoverInfoTabControl infoTabControl; - private const float cover_height = 350; - private const float info_height = 150; - private const float info_width = 220; + private readonly Box headerTopBox; + private readonly UpdateableAvatar avatar; + private readonly OsuSpriteText usernameText; + private readonly OsuSpriteText titleText; + private readonly DrawableFlag userFlag; + private readonly OsuSpriteText userCountryText; + private readonly Box userIconSeperatorBox; + private readonly FillFlowContainer userStats; + + private readonly Box headerCenterBox; + private readonly OsuSpriteText followerText; + private readonly ProfileHeaderButton messageButton; + private readonly ProfileHeaderButton expandButton; + private readonly Sprite levelBadgeSprite; + private readonly OsuSpriteText levelBadgeText; + + private readonly Bar levelProgressBar; + private readonly OsuSpriteText levelProgressText; + + private readonly OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; + + public readonly BindableBool DetailsVisible = new BindableBool(); + + private readonly Box headerDetailBox; + private readonly HasTooltipContainer totalPlayTimeTooltip; + private readonly OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; + private readonly Dictionary scoreRankInfos = new Dictionary(); + private readonly OverlinedInfoContainer detailGlobalRank, detailCountryRank; + + private const float cover_height = 150; + private const float cover_info_height = 75; + private const float info_height = 500; private const float avatar_size = 110; - private const float level_position = 30; - private const float level_height = 60; - private const float stats_width = 280; - public ProfileHeader(User user) + [Resolved(CanBeNull = true)] + private ChannelManager channelManager { get; set; } + + [Resolved(CanBeNull = true)] + private UserProfileOverlay userOverlay { get; set; } + + [Resolved(CanBeNull = true)] + private ChatOverlay chatOverlay { get; set; } + + public ProfileHeader() { + Container headerDetailContainer, expandedDetailContainer; + FillFlowContainer hiddenDetailContainer; + SpriteIcon expandButtonIcon; + RelativeSizeAxes = Axes.X; Height = cover_height + info_height; @@ -65,262 +104,491 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.75f)) }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Padding = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN, Bottom = 20, Right = stats_width + UserProfileOverlay.CONTENT_X_MARGIN }, - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Children = new Drawable[] - { - new UpdateableAvatar - { - User = user, - Size = new Vector2(avatar_size), - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, - }, - }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - X = avatar_size + 10, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - SupporterTag = new SupporterIcon - { - Alpha = 0, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = -75, - Size = new Vector2(25, 25) - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = -48, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = user.Username, - Font = @"Exo2.0-RegularItalic", - TextSize = 30, - }, - new ExternalLinkButton($@"https://osu.ppy.sh/users/{user.Id}") - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 3, Bottom = 3 }, //To better lineup with the font - }, - } - }, - countryFlag = new DrawableFlag(user.Country) - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Width = 30, - Height = 20 - } - } - }, - badgeContainer = new BadgeContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Bottom = 5 }, - Alpha = 0, - }, - } - }, - colourBar = new Box - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - X = UserProfileOverlay.CONTENT_X_MARGIN, - Height = 5, - Width = info_width, - Alpha = 0 - } } }, - new Box // this is a temporary workaround for incorrect masking behaviour of FillMode.Fill used in UserCoverBackground (see https://github.com/ppy/osu-framework/issues/1675) - { - RelativeSizeAxes = Axes.X, - Height = 1, - Y = cover_height, - Colour = OsuColour.Gray(34), - }, - infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14) - { - X = UserProfileOverlay.CONTENT_X_MARGIN, - Y = cover_height + 20, - Width = info_width, - AutoSizeAxes = Axes.Y, - ParagraphSpacing = 0.8f, - LineSpacing = 0.2f - }, - infoTextRight = new LinkFlowContainer(t => - { - t.TextSize = 14; - t.Font = @"Exo2.0-RegularItalic"; - }) - { - X = UserProfileOverlay.CONTENT_X_MARGIN + info_width + 20, - Y = cover_height + 20, - Width = info_width, - AutoSizeAxes = Axes.Y, - ParagraphSpacing = 0.8f, - LineSpacing = 0.2f - }, new Container { - X = -UserProfileOverlay.CONTENT_X_MARGIN, - RelativeSizeAxes = Axes.Y, - Width = stats_width, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Y = cover_height, + Height = cover_info_height, + RelativeSizeAxes = Axes.X, + Anchor = Anchor.TopLeft, + Origin = Anchor.BottomLeft, + Depth = -float.MaxValue, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = "Player ", + Font = "Exo2.0-Regular", + TextSize = 30 + }, + coverInfoText = new OsuSpriteText + { + Text = "Info", + Font = "Exo2.0-Regular", + TextSize = 30 + } + } + }, + infoTabControl = new CoverInfoTabControl + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = cover_info_height - 30, + Margin = new MarginPadding { Left = -UserProfileOverlay.CONTENT_X_MARGIN }, + Padding = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN } + } + } + }, + new FillFlowContainer + { + Margin = new MarginPadding { Top = cover_height }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Children = new Drawable[] { new Container { RelativeSizeAxes = Axes.X, - Y = level_position, - Height = level_height, + Height = 150, Children = new Drawable[] { - new Box + headerTopBox = new Box { - Colour = Color4.Black.Opacity(0.5f), - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, }, - levelBadge = new Sprite + new FillFlowContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Height = 50, - Width = 50, - Alpha = 0 + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Height = avatar_size, + AutoSizeAxes = Axes.X, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new[] + { + avatar = new UpdateableAvatar + { + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = avatar_size * 0.25f, + }, + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Left = 10 }, + Children = new Drawable[] + { + usernameText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 24 + }, + new FillFlowContainer + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + titleText = new OsuSpriteText + { + TextSize = 18, + Font = "Exo2.0-Regular" + }, + SupporterTag = new SupporterIcon + { + Height = 20, + Margin = new MarginPadding { Top = 5 } + }, + userIconSeperatorBox = new Box + { + RelativeSizeAxes = Axes.X, + Height = 1.5f, + Margin = new MarginPadding { Top = 10 } + }, + new Container + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 5 }, + Children = new Drawable[] + { + userFlag = new DrawableFlag + { + Size = new Vector2(30, 20) + }, + userCountryText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 17.5f, + Margin = new MarginPadding { Left = 40 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + } + } + }, + } + } + } + } + } }, - levelText = new OsuSpriteText + userStats = new FillFlowContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Y = 11, - TextSize = 20 + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Y, + Width = 300, + Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, + Padding = new MarginPadding { Vertical = 15 }, + Spacing = new Vector2(0, 2) } } }, new Container { RelativeSizeAxes = Axes.X, - Y = cover_height, - Anchor = Anchor.TopCentre, - Origin = Anchor.BottomCentre, - Height = cover_height - level_height - level_position - 5, + Height = 60, Children = new Drawable[] { - new Box + headerCenterBox = new Box { - Colour = Color4.Black.Opacity(0.5f), - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, }, - scoreText = new FillFlowContainer + new FillFlowContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 20, Vertical = 18 }, - Spacing = new Vector2(0, 2) - }, - scoreNumberText = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 20, Vertical = 18 }, - Spacing = new Vector2(0, 2) - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, Direction = FillDirection.Horizontal, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Y = -64, - Spacing = new Vector2(20, 0), - Children = new[] + Padding = new MarginPadding { Vertical = 10 }, + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - gradeSSPlus = new GradeBadge("SSPlus") { Alpha = 0 }, - gradeSS = new GradeBadge("SS") { Alpha = 0 }, + new ProfileHeaderButton + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Right = 10 }, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_user, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }, + followerText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 16, + Font = "Exo2.0-Bold" + } + } + } + } + }, + messageButton = new ProfileHeaderButton + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_envelope, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }, + } + }, + } }, - new FillFlowContainer + new Container { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Y = -18, - Spacing = new Vector2(20, 0), - Children = new[] + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Vertical = 10 }, + Width = UserProfileOverlay.CONTENT_X_MARGIN, + Child = expandButton = new ProfileHeaderButton { - gradeSPlus = new GradeBadge("SPlus") { Alpha = 0 }, - gradeS = new GradeBadge("S") { Alpha = 0 }, - gradeA = new GradeBadge("A") { Alpha = 0 }, + RelativeSizeAxes = Axes.Y, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + expandButtonIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20), + Icon = FontAwesome.fa_chevron_up, + }, + } + }, + }, + new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, + Children = new Drawable[] + { + new HasTooltipContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(40), + TooltipText = "Level", + Children = new Drawable[] + { + levelBadgeSprite = new Sprite + { + RelativeSizeAxes = Axes.Both, + }, + levelBadgeText = new OsuSpriteText + { + TextSize = 20, + Font = "Exo2.0-Medium", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + }, + expandedDetailContainer = new HasTooltipContainer + { + TooltipText = "Progress to next level", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Width = 200, + Height = 6, + Margin = new MarginPadding { Right = 50 }, + Children = new Drawable[] + { + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = levelProgressBar = new Bar + { + RelativeSizeAxes = Axes.Both, + BackgroundColour = Color4.Black, + Direction = BarDirection.LeftToRight, + } + }, + levelProgressText = new OsuSpriteText + { + Anchor = Anchor.BottomRight, + Origin = Anchor.TopRight, + Font = "Exo2.0-Bold", + TextSize = 12, + } + } + }, + hiddenDetailContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Width = 200, + AutoSizeAxes = Axes.Y, + Alpha = 0, + Spacing = new Vector2(10, 0), + Margin = new MarginPadding { Right = 50 }, + Children = new[] + { + hiddenDetailGlobal = new OverlinedInfoContainer + { + Title = "Global Ranking" + }, + hiddenDetailCountry = new OverlinedInfoContainer + { + Title = "Country Ranking" + }, + } + } } } } }, - new Container + headerDetailContainer = new Container { RelativeSizeAxes = Axes.X, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Height = info_height - 15, + AutoSizeAxes = Axes.Y, Children = new Drawable[] { - new Box + headerDetailBox = new Box { - Colour = Color4.Black.Opacity(0.25f), - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, }, - rankGraph = new RankGraph + new FillFlowContainer { - RelativeSizeAxes = Axes.Both - } + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + totalPlayTimeTooltip = new HasTooltipContainer + { + AutoSizeAxes = Axes.Both, + TooltipText = "0 hours", + Child = totalPlayTimeInfo = new OverlinedInfoContainer + { + Title = "Total Play Time", + }, + }, + medalInfo = new OverlinedInfoContainer + { + Title = "Medals" + }, + ppInfo = new OverlinedInfoContainer + { + Title = "pp" + }, + } + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Children = new[] + { + scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), + scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), + scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), + scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), + scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = 130 }, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 130, + Anchor = Anchor.TopRight, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Horizontal = 10 }, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + detailGlobalRank = new OverlinedInfoContainer(true, 110) + { + Title = "Global Ranking" + }, + detailCountryRank = new OverlinedInfoContainer(false, 110) + { + Title = "Country Ranking" + }, + } + } + } + } + } + }, } } } } }; + + infoTabControl.AddItem("Info"); + infoTabControl.AddItem("Modding"); + + DetailsVisible.ValueChanged += newValue => expandButtonIcon.Icon = newValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; + DetailsVisible.ValueChanged += newValue => hiddenDetailContainer.Alpha = newValue ? 1 : 0; + DetailsVisible.ValueChanged += newValue => expandedDetailContainer.Alpha = newValue ? 0 : 1; + DetailsVisible.ValueChanged += newValue => headerDetailContainer.Alpha = newValue ? 0 : 1; } - [BackgroundDependencyLoader] - private void load(TextureStore textures) + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, TextureStore textures) { - levelBadge.Texture = textures.Get(@"Profile/levelbadge"); + coverInfoText.Colour = colours.CommunityUserGreen; + + infoTabControl.AccentColour = colours.CommunityUserGreen; + + headerTopBox.Colour = colours.CommunityUserGrayGreenDarker; + userCountryText.Colour = colours.CommunityUserGrayGreenLighter; + userIconSeperatorBox.Colour = colours.CommunityUserGrayGreenLighter; + + headerCenterBox.Colour = colours.CommunityUserGrayGreenDark; + levelBadgeSprite.Texture = textures.Get("Profile/levelbadge"); + levelBadgeSprite.Colour = colours.Yellow; + levelProgressBar.AccentColour = colours.Yellow; + + hiddenDetailGlobal.LineColour = colours.Yellow; + hiddenDetailCountry.LineColour = colours.Yellow; + + headerDetailBox.Colour = colours.CommunityUserGrayGreenDarkest; + totalPlayTimeInfo.LineColour = colours.Yellow; + medalInfo.LineColour = colours.GreenLight; + ppInfo.LineColour = colours.Red; + + detailGlobalRank.LineColour = colours.Yellow; + detailCountryRank.LineColour = colours.Yellow; } private User user; public User User { - get { return user; } + get => user; set { user = value; @@ -340,9 +608,79 @@ namespace osu.Game.Overlays.Profile Depth = float.MaxValue, }, coverContainer.Add); - if (user.IsSupporter) - SupporterTag.Show(); + avatar.User = User; + usernameText.Text = user.Username; + userFlag.Country = user.Country; + userCountryText.Text = user.Country?.FullName; + SupporterTag.SupporterLevel = user.SupportLevel; + if(user.Title != null) + titleText.Text = user.Title; + titleText.Colour = OsuColour.FromHex(user.Colour ?? "fff"); + userStats.Add(new UserStatsLine("Ranked Score", user.Statistics.RankedScore.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Hit Accuracy", Math.Round(user.Statistics.Accuracy, 2).ToString("#0.00'%'"))); + userStats.Add(new UserStatsLine("Play Count", user.Statistics.PlayCount.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Total Score", user.Statistics.TotalScore.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Total Hits", user.Statistics.TotalHits.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Maximum Combo", user.Statistics.MaxCombo.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Replays Watched by Others", user.Statistics.ReplaysWatched.ToString("#,##0"))); + + followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; + + if (!user.PMFriendsOnly) + messageButton.Action = () => + { + channelManager?.OpenPrivateChannel(user); + userOverlay?.Hide(); + chatOverlay?.Show(); + }; + + expandButton.Action = DetailsVisible.Toggle; + + levelBadgeText.Text = user.Statistics.Level.Current.ToString(); + levelProgressBar.Length = user.Statistics.Level.Progress / 100f; + levelProgressText.Text = user.Statistics.Level.Progress.ToString("0'%'"); + + hiddenDetailGlobal.Content = user.Statistics.Ranks.Global?.ToString("#,##0") ?? "-"; + hiddenDetailCountry.Content = user.Statistics.Ranks.Country?.ToString("#,##0") ?? "-"; + + medalInfo.Content = user.Achievements.Length.ToString(); + ppInfo.Content = user.Statistics.PP?.ToString("#,##0") ?? "0"; + + string formatTime(int? secondsNull) + { + if (secondsNull == null) return "0h 0m"; + + int seconds = secondsNull.Value; + string time = ""; + + int days = seconds / 86400; + seconds -= days * 86400; + if (days > 0) + time += days + "d "; + + int hours = seconds / 3600; + seconds -= hours * 3600; + time += hours + "h "; + + int minutes = seconds / 60; + time += minutes + "m"; + + return time; + } + + totalPlayTimeInfo.Content = formatTime(user.Statistics.PlayTime); + totalPlayTimeTooltip.TooltipText = (user.Statistics.PlayTime ?? 0) / 3600 + " hours"; + + foreach (var scoreRankInfo in scoreRankInfos) + scoreRankInfo.Value.RankCount = user.Statistics.GradesCount.GetForScoreRank(scoreRankInfo.Key); + + detailGlobalRank.Content = user.Statistics.Ranks.Global?.ToString("#,##0") ?? "-"; + detailCountryRank.Content = user.Statistics.Ranks.Country?.ToString("#,##0") ?? "-"; + + rankGraph.User.Value = user; + + /* if (!string.IsNullOrEmpty(user.Colour)) { colourBar.Colour = OsuColour.FromHex(user.Colour); @@ -457,24 +795,315 @@ namespace osu.Game.Overlays.Profile rankGraph.User.Value = user; } - badgeContainer.ShowBadges(user.Badges); + badgeContainer.ShowBadges(user.Badges);*/ } - private void tryAddInfoRightLine(FontAwesome icon, string str, string url = null) + private class CoverInfoTabControl : TabControl { - if (string.IsNullOrEmpty(str)) return; + private readonly Box bar; - infoTextRight.AddIcon(icon); - if (url != null) + private Color4 accentColour; + public Color4 AccentColour { - infoTextRight.AddLink(" " + str, url); - } - else - { - infoTextRight.AddText(" " + str); + get => accentColour; + set + { + if (accentColour == value) return; + + accentColour = value; + + bar.Colour = value; + + foreach (TabItem tabItem in TabContainer) + { + ((CoverInfoTabItem)tabItem).AccentColour = value; + } + } } - infoTextRight.NewLine(); + public MarginPadding Padding + { + set => TabContainer.Padding = value; + get => TabContainer.Padding; + } + + public CoverInfoTabControl() + { + TabContainer.Masking = false; + TabContainer.Spacing = new Vector2(20, 0); + + AddInternal(bar = new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Anchor = Anchor.BottomLeft, + Origin = Anchor.CentreLeft + }); + } + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(string value) => new CoverInfoTabItem(value) + { + AccentColour = AccentColour + }; + + private class CoverInfoTabItem : TabItem + { + private readonly OsuSpriteText text; + private readonly Drawable bar; + + private Color4 accentColour; + public Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + + bar.Colour = value; + if (!Active) text.Colour = value; + } + } + + public CoverInfoTabItem(string value) + : base(value) + { + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + + Children = new[] + { + text = new OsuSpriteText + { + Margin = new MarginPadding { Bottom = 15 }, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Text = value, + TextSize = 14, + Font = "Exo2.0-Bold", + }, + bar = new Circle + { + RelativeSizeAxes = Axes.X, + Height = 0, + Origin = Anchor.CentreLeft, + Anchor = Anchor.BottomLeft, + }, + new HoverClickSounds() + }; + } + + protected override bool OnHover(HoverEvent e) + { + if (!Active) + onActivated(true); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + if (!Active) + OnDeactivated(); + } + + protected override void OnActivated() + { + onActivated(); + } + + protected override void OnDeactivated() + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + bar.ResizeHeightTo(0, 120, Easing.InQuad); + text.Font = "Exo2.0-Medium"; + } + + private void onActivated(bool fake = false) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); + if (!fake) + text.Font = "Exo2.0-Bold"; + } + } + } + + private class UserStatsLine : Container + { + private readonly OsuSpriteText rightText; + + public UserStatsLine(string left, string right) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + new OsuSpriteText + { + TextSize = 15, + Text = left, + Font = "Exo2.0-Medium" + }, + rightText = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + TextSize = 15, + Text = right, + Font = "Exo2.0-Medium" + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + rightText.Colour = colours.BlueLight; + } + } + + private class ProfileHeaderButton : OsuHoverContainer + { + private readonly Box background; + private readonly Container content; + + protected override Container Content => content; + + protected override IEnumerable EffectTargets => new[] { background }; + + public ProfileHeaderButton() + { + HoverColour = Color4.Black.Opacity(0.75f); + IdleColour = Color4.Black.Opacity(0.7f); + AutoSizeAxes = Axes.X; + + base.Content.Add(new CircularContainer + { + Masking = true, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + content = new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 10 }, + } + } + }); + } + } + + private class HasTooltipContainer : Container, IHasTooltip + { + public string TooltipText { get; set; } + } + + private class OverlinedInfoContainer : CompositeDrawable + { + private readonly Circle line; + private readonly OsuSpriteText title, content; + + public string Title + { + set => title.Text = value; + } + + public string Content + { + set => content.Text = value; + } + + public Color4 LineColour + { + set => line.Colour = value; + } + + public OverlinedInfoContainer(bool big = false, int minimumWidth = 60) + { + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + line = new Circle + { + RelativeSizeAxes = Axes.X, + Height = 4, + }, + title = new OsuSpriteText + { + Font = "Exo2.0-Bold", + TextSize = big ? 14 : 12, + }, + content = new OsuSpriteText + { + Font = "Exo2.0-Light", + TextSize = big ? 40 : 18, + }, + new Container //Add a minimum size to the FillFlowContainer + { + Width = minimumWidth, + } + } + }; + } + } + + public class ScoreRankInfo : CompositeDrawable + { + private readonly ScoreRank rank; + private readonly Sprite rankSprite; + private readonly OsuSpriteText rankCount; + + public int RankCount + { + set => rankCount.Text = value.ToString("#,##0"); + } + + public ScoreRankInfo(ScoreRank rank) + { + this.rank = rank; + + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 56, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + rankSprite = new Sprite + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + }, + rankCount = new OsuSpriteText + { + Font = "Exo2.0-Bold", + TextSize = 12, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + rankSprite.Texture = textures.Get($"Grades/{rank.GetDescription()}"); + } } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index c15f464c7c..ca99f07d9b 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays private SectionsContainer sectionsContainer; private ProfileTabControl tabs; - public const float CONTENT_X_MARGIN = 50; + public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() { @@ -113,12 +113,10 @@ namespace osu.Game.Overlays Colour = OsuColour.Gray(0.2f) }); - Header = new ProfileHeader(user); - Add(sectionsContainer = new SectionsContainer { RelativeSizeAxes = Axes.Both, - ExpandableHeader = Header, + ExpandableHeader = Header = new ProfileHeader(), FixedHeader = tabs, HeaderBackground = new Box { diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index a5d8c03a67..485c953b75 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -59,6 +59,9 @@ namespace osu.Game.Users [JsonProperty(@"is_supporter")] public bool IsSupporter; + [JsonProperty(@"support_level")] + public int SupportLevel; + [JsonProperty(@"is_gmt")] public bool IsGMT; @@ -71,6 +74,9 @@ namespace osu.Game.Users [JsonProperty(@"is_active")] public bool Active; + [JsonProperty(@"pm_friends_only")] + public bool PMFriendsOnly; + [JsonProperty(@"interests")] public string Interests; @@ -104,6 +110,9 @@ namespace osu.Game.Users [JsonProperty(@"post_count")] public int PostCount; + [JsonProperty(@"follower_count")] + public int[] FollowerCount; + [JsonProperty(@"playstyle")] public string[] PlayStyle; @@ -143,6 +152,18 @@ namespace osu.Game.Users [JsonProperty("badges")] public Badge[] Badges; + [JsonProperty("user_achievements")] + public UserAchievement[] Achievements; + + public class UserAchievement + { + [JsonProperty("achieved_at")] + public DateTimeOffset AchievedAt; + + [JsonProperty("achievement_id")] + public int ID; + } + public override string ToString() => Username; /// diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index d86f608bd1..3d0127bba4 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -185,8 +185,8 @@ namespace osu.Game.Users { infoContainer.Add(new SupporterIcon { - RelativeSizeAxes = Axes.Y, - Width = 20f, + Height = 20f, + SupporterLevel = user.SupportLevel }); } diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index f04bfb62bb..c400a3f15b 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -1,7 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using Newtonsoft.Json; +using osu.Game.Scoring; namespace osu.Game.Users { @@ -37,6 +39,9 @@ namespace osu.Game.Users [JsonProperty(@"play_count")] public int PlayCount; + [JsonProperty(@"play_time")] + public int? PlayTime; + [JsonProperty(@"total_score")] public long TotalScore; @@ -68,6 +73,19 @@ namespace osu.Game.Users [JsonProperty(@"a")] public int A; + + public int GetForScoreRank(ScoreRank rank) + { + switch (rank) + { + case ScoreRank.XH: return SSPlus; + case ScoreRank.X: return SS; + case ScoreRank.SH: return SPlus; + case ScoreRank.S: return S; + case ScoreRank.A: return A; + default: throw new ArgumentException($"API does not return {rank.ToString()}"); + } + } } public struct UserRanks diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index d6882282e6..170a7bd8c9 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -208,6 +208,7 @@ MD5 NS OS + PM RGB RNG SHA From 2fe80d556844d82c8029d8999a08c8b5166e5094 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 22 Dec 2018 21:50:25 +0100 Subject: [PATCH 002/278] Update ProfileHeader to the new design --- .../Visual/TestCaseBadgeContainer.cs | 62 --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 1 - .../Graphics/Containers/SectionsContainer.cs | 11 + osu.Game/Graphics/UserInterface/LineGraph.cs | 11 +- .../Profile/Components/DrawableJoinDate.cs | 20 - .../Overlays/Profile/Components/GradeBadge.cs | 50 --- .../Overlays/Profile/Header/BadgeContainer.cs | 198 --------- .../Profile/Header/ProfileHeaderTabControl.cs | 149 +++++++ osu.Game/Overlays/Profile/Header/RankGraph.cs | 194 +++++--- osu.Game/Overlays/Profile/ProfileHeader.cs | 419 ++++++++---------- 10 files changed, 480 insertions(+), 635 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCaseBadgeContainer.cs delete mode 100644 osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs delete mode 100644 osu.Game/Overlays/Profile/Components/GradeBadge.cs delete mode 100644 osu.Game/Overlays/Profile/Header/BadgeContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs diff --git a/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs b/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs deleted file mode 100644 index 8177e2e272..0000000000 --- a/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Game.Overlays.Profile.Header; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual -{ - [TestFixture] - public class TestCaseBadgeContainer : OsuTestCase - { - public override IReadOnlyList RequiredTypes => new[] { typeof(BadgeContainer) }; - - public TestCaseBadgeContainer() - { - BadgeContainer badgeContainer; - - Child = badgeContainer = new BadgeContainer - { - RelativeSizeAxes = Axes.Both - }; - - AddStep("Show 1 badge", () => badgeContainer.ShowBadges(new[] - { - new Badge - { - AwardedAt = DateTimeOffset.Now, - Description = "Appreciates compasses", - ImageUrl = "https://assets.ppy.sh/profile-badges/mg2018-1star.png", - } - })); - - AddStep("Show 2 badges", () => badgeContainer.ShowBadges(new[] - { - new Badge - { - AwardedAt = DateTimeOffset.Now, - Description = "Contributed to osu!lazer testing", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.png", - }, - new Badge - { - AwardedAt = DateTimeOffset.Now, - Description = "Appreciates compasses", - ImageUrl = "https://assets.ppy.sh/profile-badges/mg2018-1star.png", - } - })); - - AddStep("Show many badges", () => badgeContainer.ShowBadges(Enumerable.Range(1, 20).Select(i => new Badge - { - AwardedAt = DateTimeOffset.Now, - Description = $"Contributed to osu!lazer testing {i} times", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", - }).ToArray())); - } - } -} diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index ce41bc22ff..cff55c2506 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -28,7 +28,6 @@ namespace osu.Game.Tests.Visual typeof(UserProfileOverlay), typeof(RankGraph), typeof(LineGraph), - typeof(BadgeContainer), typeof(SectionsContainer<>), typeof(SupporterIcon) }; diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index 36fdbe6e94..f16b5773ea 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -141,6 +141,17 @@ namespace osu.Game.Graphics.Containers public void ScrollToTop() => scrollContainer.ScrollTo(0); + public override void InvalidateFromChild(Invalidation invalidation, Drawable source = null) + { + base.InvalidateFromChild(invalidation, source); + + if ((invalidation & Invalidation.DrawSize) != 0) + { + if (source == ExpandableHeader) //We need to recalculate the positions if the ExpandableHeader changed its size + lastKnownScroll = -1; + } + } + private float lastKnownScroll; protected override void UpdateAfterChildren() { diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index c84c500201..c750f7a89d 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -9,6 +9,7 @@ using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; +using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { @@ -63,13 +64,19 @@ namespace osu.Game.Graphics.UserInterface } } + public Color4 LineColour + { + get => maskingContainer.Colour; + set => maskingContainer.Colour = value; + } + public LineGraph() { Add(maskingContainer = new Container { Masking = true, RelativeSizeAxes = Axes.Both, - Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathWidth = 1 } + Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathWidth = 1.5f } }); } @@ -103,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface for (int i = 0; i < values.Length; i++) { float x = (i + count - values.Length) / (float)(count - 1) * DrawWidth - 1; - float y = GetYPosition(values[i]) * DrawHeight - 1; + float y = GetYPosition(values[i]) * DrawHeight - path.PathWidth; // the -1 is for inner offset in path (actually -PathWidth) path.AddVertex(new Vector2(x, y)); } diff --git a/osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs b/osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs deleted file mode 100644 index 11ee329f33..0000000000 --- a/osu.Game/Overlays/Profile/Components/DrawableJoinDate.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Game.Graphics; - -namespace osu.Game.Overlays.Profile.Components -{ - public class DrawableJoinDate : DrawableDate - { - public DrawableJoinDate(DateTimeOffset date) - : base(date) - { - } - - protected override string Format() => Text = Date.ToUniversalTime().Year < 2008 ? "Here since the beginning" : $"{Date:MMMM yyyy}"; - - public override string TooltipText => $"{Date:MMMM d, yyyy}"; - } -} diff --git a/osu.Game/Overlays/Profile/Components/GradeBadge.cs b/osu.Game/Overlays/Profile/Components/GradeBadge.cs deleted file mode 100644 index 14a47e8d03..0000000000 --- a/osu.Game/Overlays/Profile/Components/GradeBadge.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Overlays.Profile.Components -{ - public class GradeBadge : Container - { - private const float width = 50; - private readonly string grade; - private readonly Sprite badge; - private readonly SpriteText numberText; - - public int DisplayCount - { - set => numberText.Text = value.ToString(@"#,0"); - } - - public GradeBadge(string grade) - { - this.grade = grade; - Width = width; - Height = 41; - Add(badge = new Sprite - { - Width = width, - Height = 26 - }); - Add(numberText = new OsuSpriteText - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - TextSize = 14, - Font = @"Exo2.0-Bold" - }); - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - badge.Texture = textures.Get($"Grades/{grade}"); - } - } -} diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs deleted file mode 100644 index 06fef22309..0000000000 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -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.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Users; -using osuTK; - -namespace osu.Game.Overlays.Profile.Header -{ - public class BadgeContainer : Container - { - private static readonly Vector2 badge_size = new Vector2(86, 40); - private static readonly MarginPadding outer_padding = new MarginPadding(3); - - private OsuSpriteText badgeCountText; - private FillFlowContainer badgeFlowContainer; - private FillFlowContainer outerBadgeContainer; - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Child = new Container - { - Masking = true, - CornerRadius = 4, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray3 - }, - outerBadgeContainer = new OuterBadgeContainer(onOuterHover, onOuterHoverLost) - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Direction = FillDirection.Vertical, - Padding = outer_padding, - Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - badgeCountText = new OsuSpriteText - { - Alpha = 0, - TextSize = 12, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Font = "Exo2.0-Regular" - }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - AutoSizeAxes = Axes.Both, - Child = badgeFlowContainer = new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - } - } - } - }, - } - }; - - Scheduler.AddDelayed(rotateBadges, 3000, true); - } - - private void rotateBadges() - { - if (outerBadgeContainer.IsHovered) return; - - visibleBadge = (visibleBadge + 1) % badgeCount; - - badgeFlowContainer.MoveToX(-DrawableBadge.DRAWABLE_BADGE_SIZE.X * visibleBadge, 500, Easing.InOutQuad); - } - - private int visibleBadge; - private int badgeCount; - - public void ShowBadges(Badge[] badges) - { - if (badges == null || badges.Length == 0) - { - Hide(); - return; - } - - badgeCount = badges.Length; - - badgeCountText.FadeTo(badgeCount > 1 ? 1 : 0); - badgeCountText.Text = $"{badges.Length} badges"; - - Show(); - visibleBadge = 0; - - badgeFlowContainer.Clear(); - for (var index = 0; index < badges.Length; index++) - { - int displayIndex = index; - LoadComponentAsync(new DrawableBadge(badges[index]) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, asyncBadge => - { - badgeFlowContainer.Add(asyncBadge); - - // load in stable order regardless of async load order. - badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex); - }); - } - } - - private void onOuterHover() - { - badgeFlowContainer.ClearTransforms(); - badgeFlowContainer.X = 0; - badgeFlowContainer.Direction = FillDirection.Full; - outerBadgeContainer.AutoSizeAxes = Axes.Both; - - badgeFlowContainer.MaximumSize = new Vector2(ChildSize.X, float.MaxValue); - } - - private void onOuterHoverLost() - { - badgeFlowContainer.X = -DrawableBadge.DRAWABLE_BADGE_SIZE.X * visibleBadge; - badgeFlowContainer.Direction = FillDirection.Horizontal; - outerBadgeContainer.AutoSizeAxes = Axes.Y; - outerBadgeContainer.Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal; - } - - private class OuterBadgeContainer : FillFlowContainer - { - private readonly Action hoverAction; - private readonly Action hoverLostAction; - - public OuterBadgeContainer(Action hoverAction, Action hoverLostAction) - { - this.hoverAction = hoverAction; - this.hoverLostAction = hoverLostAction; - } - - protected override bool OnHover(HoverEvent e) - { - hoverAction(); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) => hoverLostAction(); - } - - private class DrawableBadge : Container, IHasTooltip - { - public static readonly Vector2 DRAWABLE_BADGE_SIZE = badge_size + outer_padding.Total; - - private readonly Badge badge; - - public DrawableBadge(Badge badge) - { - this.badge = badge; - Padding = outer_padding; - Size = DRAWABLE_BADGE_SIZE; - } - - [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) - { - Child = new Sprite - { - FillMode = FillMode.Fit, - RelativeSizeAxes = Axes.Both, - Texture = textures.Get(badge.ImageUrl), - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - Child.FadeInFromZero(200); - } - - public string TooltipText => badge.Description; - } - } -} diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs new file mode 100644 index 0000000000..b067273b04 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -0,0 +1,149 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile +{ + public class ProfileHeaderTabControl : TabControl + { + private readonly Box bar; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) return; + + accentColour = value; + + bar.Colour = value; + + foreach (TabItem tabItem in TabContainer) + { + ((ProfileHeaderTabItem)tabItem).AccentColour = value; + } + } + } + + public MarginPadding Padding + { + set => TabContainer.Padding = value; + get => TabContainer.Padding; + } + + public ProfileHeaderTabControl() + { + TabContainer.Masking = false; + TabContainer.Spacing = new Vector2(20, 0); + + AddInternal(bar = new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Anchor = Anchor.BottomLeft, + Origin = Anchor.CentreLeft + }); + } + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(string value) => new ProfileHeaderTabItem(value) + { + AccentColour = AccentColour + }; + + private class ProfileHeaderTabItem : TabItem + { + private readonly OsuSpriteText text; + private readonly Drawable bar; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + + bar.Colour = value; + if (!Active) text.Colour = value; + } + } + + public ProfileHeaderTabItem(string value) + : base(value) + { + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + + Children = new[] + { + text = new OsuSpriteText + { + Margin = new MarginPadding { Bottom = 15 }, + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Text = value, + TextSize = 14, + Font = "Exo2.0-Bold", + }, + bar = new Circle + { + RelativeSizeAxes = Axes.X, + Height = 0, + Origin = Anchor.CentreLeft, + Anchor = Anchor.BottomLeft, + }, + new HoverClickSounds() + }; + } + + protected override bool OnHover(HoverEvent e) + { + if (!Active) + onActivated(true); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + if (!Active) + OnDeactivated(); + } + + protected override void OnActivated() + { + onActivated(); + } + + protected override void OnDeactivated() + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + bar.ResizeHeightTo(0, 120, Easing.InQuad); + text.Font = "Exo2.0-Medium"; + } + + private void onActivated(bool fake = false) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); + if (!fake) + text.Font = "Exo2.0-Bold"; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/RankGraph.cs b/osu.Game/Overlays/Profile/Header/RankGraph.cs index f74c8b5069..f67a8e47d4 100644 --- a/osu.Game/Overlays/Profile/Header/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/RankGraph.cs @@ -8,8 +8,8 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -19,19 +19,18 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class RankGraph : Container + public class RankGraph : Container, IHasCustomTooltip { - private const float primary_textsize = 25; private const float secondary_textsize = 13; private const float padding = 10; private const float fade_duration = 150; private const int ranked_days = 88; - private readonly SpriteText rankText, performanceText, relativeText; private readonly RankChartLineGraph graph; private readonly OsuSpriteText placeholder; private KeyValuePair[] ranks; + private int dayIndex; public Bindable User = new Bindable(); public RankGraph() @@ -44,43 +43,20 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.Centre, Origin = Anchor.Centre, Text = "No recent plays", - TextSize = 14, - Font = @"Exo2.0-RegularItalic", - }, - rankText = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Font = @"Exo2.0-RegularItalic", - TextSize = primary_textsize - }, - relativeText = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Font = @"Exo2.0-RegularItalic", - Y = 25, - TextSize = secondary_textsize - }, - performanceText = new OsuSpriteText - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Font = @"Exo2.0-RegularItalic", - TextSize = secondary_textsize + TextSize = 12, + Font = @"Exo2.0-Regular", }, graph = new RankChartLineGraph { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = 60, + RelativeSizeAxes = Axes.Both, Y = -secondary_textsize, Alpha = 0, } }; - graph.OnBallMove += showHistoryRankTexts; + graph.OnBallMove += i => dayIndex = i; User.ValueChanged += userChanged; } @@ -88,7 +64,7 @@ namespace osu.Game.Overlays.Profile.Header [BackgroundDependencyLoader] private void load(OsuColour colours) { - graph.Colour = colours.Yellow; + graph.LineColour = colours.Yellow; } private void userChanged(User user) @@ -97,9 +73,6 @@ namespace osu.Game.Overlays.Profile.Header if (user?.Statistics?.Ranks.Global == null) { - rankText.Text = string.Empty; - performanceText.Text = string.Empty; - relativeText.Text = string.Empty; graph.FadeOut(fade_duration, Easing.Out); ranks = null; return; @@ -114,27 +87,9 @@ namespace osu.Game.Overlays.Profile.Header graph.DefaultValueCount = ranks.Length; graph.Values = ranks.Select(x => -(float)Math.Log(x.Value)); - graph.SetStaticBallPosition(); } graph.FadeTo(ranks.Length > 1 ? 1 : 0, fade_duration, Easing.Out); - - updateRankTexts(); - } - - private void updateRankTexts() - { - var user = User.Value; - - performanceText.Text = user.Statistics.PP != null ? $"{user.Statistics.PP:#,0}pp" : string.Empty; - rankText.Text = user.Statistics.Ranks.Global > 0 ? $"#{user.Statistics.Ranks.Global:#,0}" : "no rank"; - relativeText.Text = user.Country != null && user.Statistics.Ranks.Country > 0 ? $"{user.Country.FullName} #{user.Statistics.Ranks.Country:#,0}" : "no rank"; - } - - private void showHistoryRankTexts(int dayIndex) - { - rankText.Text = $"#{ranks[dayIndex].Value:#,0}"; - relativeText.Text = dayIndex + 1 == ranks.Length ? "Now" : $"{ranked_days - ranks[dayIndex].Key} days ago"; } protected override bool OnHover(HoverEvent e) @@ -160,7 +115,6 @@ namespace osu.Game.Overlays.Profile.Header if (ranks?.Length > 1) { graph.HideBall(); - updateRankTexts(); } base.OnHoverLost(e); @@ -168,44 +122,62 @@ namespace osu.Game.Overlays.Profile.Header private class RankChartLineGraph : LineGraph { - private readonly CircularContainer staticBall; private readonly CircularContainer movingBall; + private readonly Box ballBg; + private readonly Box movingBar; public Action OnBallMove; public RankChartLineGraph() { - Add(staticBall = new CircularContainer + Add(movingBar = new Box { - Origin = Anchor.Centre, - Size = new Vector2(8), - Masking = true, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Y, + Width = 1.5f, + Alpha = 0, RelativePositionAxes = Axes.Both, - Child = new Box { RelativeSizeAxes = Axes.Both } }); + Add(movingBall = new CircularContainer { Origin = Anchor.Centre, - Size = new Vector2(8), + Size = new Vector2(18), Alpha = 0, Masking = true, + BorderThickness = 4, RelativePositionAxes = Axes.Both, - Child = new Box { RelativeSizeAxes = Axes.Both } + Child = ballBg = new Box { RelativeSizeAxes = Axes.Both } }); } - public void SetStaticBallPosition() => staticBall.Position = new Vector2(1, GetYPosition(Values.Last())); + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + ballBg.Colour = colours.CommunityUserGrayGreenDarkest; + movingBall.BorderColour = colours.Yellow; + movingBar.Colour = colours.Yellow; + } public void UpdateBallPosition(float mouseXPosition) { int index = calculateIndex(mouseXPosition); movingBall.Position = calculateBallPosition(index); + movingBar.X = movingBall.X; OnBallMove.Invoke(index); } - public void ShowBall() => movingBall.FadeIn(fade_duration); + public void ShowBall() + { + movingBall.FadeIn(fade_duration); + movingBar.FadeIn(fade_duration); + } - public void HideBall() => movingBall.FadeOut(fade_duration); + public void HideBall() + { + movingBall.FadeOut(fade_duration); + movingBar.FadeOut(fade_duration); + } private int calculateIndex(float mouseXPosition) => (int)Math.Round(mouseXPosition / DrawWidth * (DefaultValueCount - 1)); @@ -215,5 +187,97 @@ namespace osu.Game.Overlays.Profile.Header return new Vector2(index / (float)(DefaultValueCount - 1), y); } } + + public string TooltipText => User.Value?.Statistics?.Ranks.Global == null ? "" : $"{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}"; + + public ITooltip GetCustomTooltip() => new RankGraphTooltip(this); + + public class RankGraphTooltip : VisibilityContainer, ITooltip + { + private readonly RankGraph graph; + private readonly OsuSpriteText globalRankingText, timeText; + private readonly Box background; + + public string TooltipText { get; set; } + + public RankGraphTooltip(RankGraph graph) + { + this.graph = graph; + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 10; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new OsuSpriteText + { + Font = "Exo2.0-Bold", + TextSize = 12, + Text = "Global Ranking " + }, + globalRankingText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 12, + } + } + }, + timeText = new OsuSpriteText + { + TextSize = 12, + Font = "Exo2.0-Regular" + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.CommunityUserGrayGreenDarker; + } + + public void Refresh() + { + var info = TooltipText.Split('|'); + globalRankingText.Text = info[0]; + timeText.Text = info[1] == "0" ? "now" : $"{info[1]} days ago"; + } + + private bool instantMove = true; + + public void Move(Vector2 pos) + { + if (instantMove) + { + Position = pos; + instantMove = false; + } + else + this.MoveTo(pos, 200, Easing.OutQuint); + } + + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); + } } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index b35ae50c5e..6ab178cfe1 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -15,8 +15,6 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -36,7 +34,7 @@ namespace osu.Game.Overlays.Profile public readonly SupporterIcon SupporterTag; private readonly Container coverContainer; private readonly OsuSpriteText coverInfoText; - private readonly CoverInfoTabControl infoTabControl; + private readonly ProfileHeaderTabControl infoTabControl; private readonly Box headerTopBox; private readonly UpdateableAvatar avatar; @@ -67,9 +65,16 @@ namespace osu.Game.Overlays.Profile private readonly Dictionary scoreRankInfos = new Dictionary(); private readonly OverlinedInfoContainer detailGlobalRank, detailCountryRank; + private readonly Box headerBadgeBox; + private readonly FillFlowContainer badgeFlowContainer; + private readonly Container badgeContainer; + + private readonly Box headerBottomBox; + private readonly LinkFlowContainer bottomTopLinkContainer; + private readonly LinkFlowContainer bottomLinkContainer; + private const float cover_height = 150; private const float cover_info_height = 75; - private const float info_height = 500; private const float avatar_size = 110; [Resolved(CanBeNull = true)] @@ -83,12 +88,12 @@ namespace osu.Game.Overlays.Profile public ProfileHeader() { - Container headerDetailContainer, expandedDetailContainer; - FillFlowContainer hiddenDetailContainer; + Container expandedDetailContainer; + FillFlowContainer hiddenDetailContainer, headerDetailContainer; SpriteIcon expandButtonIcon; RelativeSizeAxes = Axes.X; - Height = cover_height + info_height; + AutoSizeAxes = Axes.Y; Children = new Drawable[] { @@ -137,7 +142,7 @@ namespace osu.Game.Overlays.Profile } } }, - infoTabControl = new CoverInfoTabControl + infoTabControl = new ProfileHeaderTabControl { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -181,7 +186,7 @@ namespace osu.Game.Overlays.Profile Size = new Vector2(avatar_size), Masking = true, CornerRadius = avatar_size * 0.25f, - OpenOnClick = { Value = false }, + OpenOnClick = { Value = false }, }, new Container { @@ -437,7 +442,7 @@ namespace osu.Game.Overlays.Profile } } }, - headerDetailContainer = new Container + new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -447,7 +452,7 @@ namespace osu.Game.Overlays.Profile { RelativeSizeAxes = Axes.Both, }, - new FillFlowContainer + headerDetailContainer = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -539,11 +544,82 @@ namespace osu.Game.Overlays.Profile } } } - } + }, } }, } - } + }, + badgeContainer = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Alpha = 0, + Children = new Drawable[] + { + headerBadgeBox = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container //artificial shadow + { + RelativeSizeAxes = Axes.X, + Height = 3, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = Color4.Black.Opacity(0.2f), + TopRight = Color4.Black.Opacity(0.2f), + BottomLeft = Color4.Black.Opacity(0), + BottomRight = Color4.Black.Opacity(0) + } + }, + }, + badgeFlowContainer = new FillFlowContainer + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5 }, + Spacing = new Vector2(10, 10), + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + } + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + headerBottomBox = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + bottomTopLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + bottomLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } + } + } + }, } } }; @@ -557,6 +633,8 @@ namespace osu.Game.Overlays.Profile DetailsVisible.ValueChanged += newValue => headerDetailContainer.Alpha = newValue ? 0 : 1; } + private Color4 communityUserGrayGreenLighter; + [BackgroundDependencyLoader(true)] private void load(OsuColour colours, TextureStore textures) { @@ -583,9 +661,12 @@ namespace osu.Game.Overlays.Profile detailGlobalRank.LineColour = colours.Yellow; detailCountryRank.LineColour = colours.Yellow; - } - private readonly OsuSpriteText usernameText; + headerBadgeBox.Colour = colours.CommunityUserGrayGreenDarkest; + headerBottomBox.Colour = colours.CommunityUserGrayGreenDarker; + + communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; + } private User user; @@ -683,67 +764,68 @@ namespace osu.Game.Overlays.Profile rankGraph.User.Value = user; - /* - if (!string.IsNullOrEmpty(user.Colour)) + var badges = User.Badges; + if (badges.Length > 0) { - colourBar.Colour = OsuColour.FromHex(user.Colour); - colourBar.Show(); + badgeContainer.Show(); + for (var index = 0; index < badges.Length; index++) + { + int displayIndex = index; + LoadComponentAsync(new DrawableBadge(badges[index]), asyncBadge => + { + badgeFlowContainer.Add(asyncBadge); + + // load in stable order regardless of async load order. + badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex); + }); + } } - void boldItalic(SpriteText t) => t.Font = @"Exo2.0-BoldItalic"; - void lightText(SpriteText t) => t.Alpha = 0.8f; - - OsuSpriteText createScoreText(string text) => new OsuSpriteText - { - TextSize = 14, - Text = text - }; - - OsuSpriteText createScoreNumberText(string text) => new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-Bold", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Text = text - }; - - if (user.Country != null) - { - infoTextLeft.AddText("From ", lightText); - infoTextLeft.AddText(user.Country.FullName, boldItalic); - countryFlag.Country = user.Country; - } - - infoTextLeft.NewParagraph(); + void bold(SpriteText t) => t.Font = @"Exo2.0-Bold"; + void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); if (user.JoinDate.ToUniversalTime().Year < 2008) { - infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), lightText); + bottomTopLinkContainer.AddText("Here since the beginning"); } else { - infoTextLeft.AddText("Joined ", lightText); - infoTextLeft.AddText(new DrawableJoinDate(user.JoinDate), boldItalic); + bottomTopLinkContainer.AddText("Joined "); + bottomTopLinkContainer.AddText(new DrawableDate(user.JoinDate), bold); } + addSpacer(bottomTopLinkContainer); + if (user.LastVisit.HasValue) { - infoTextLeft.NewLine(); - infoTextLeft.AddText("Last seen ", lightText); - infoTextLeft.AddText(new DrawableDate(user.LastVisit.Value), boldItalic); - infoTextLeft.NewParagraph(); + bottomTopLinkContainer.AddText("Last seen "); + bottomTopLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), bold); } - if (user.PlayStyle?.Length > 0) + addSpacer(bottomTopLinkContainer); + + bottomTopLinkContainer.AddText("Contributed "); + bottomTopLinkContainer.AddLink($@"{user.PostCount} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); + + void tryAddInfo(FontAwesome icon, string content, string link = null) { - infoTextLeft.AddText("Plays with ", lightText); - infoTextLeft.AddText(string.Join(", ", user.PlayStyle), boldItalic); - } + if (string.IsNullOrEmpty(content)) return; - infoTextLeft.NewLine(); - infoTextLeft.AddText("Contributed ", lightText); - infoTextLeft.AddLink($@"{user.PostCount} forum posts", url: $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: boldItalic); + bottomLinkContainer.AddIcon(icon, text => + { + text.TextSize = 10; + text.Colour = communityUserGrayGreenLighter; + }); + if (link != null) + { + bottomLinkContainer.AddLink(" " + content, link, creationParameters: bold); + } + else + { + bottomLinkContainer.AddText(" " + content, bold); + } + addSpacer(bottomLinkContainer); + } string websiteWithoutProtcol = user.Website; if (!string.IsNullOrEmpty(websiteWithoutProtcol)) @@ -753,185 +835,16 @@ namespace osu.Game.Overlays.Profile websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); } - tryAddInfoRightLine(FontAwesome.fa_map_marker, user.Location); - tryAddInfoRightLine(FontAwesome.fa_heart_o, user.Interests); - tryAddInfoRightLine(FontAwesome.fa_suitcase, user.Occupation); - infoTextRight.NewParagraph(); + tryAddInfo(FontAwesome.fa_map_marker, user.Location); + tryAddInfo(FontAwesome.fa_heart_o, user.Interests); + tryAddInfo(FontAwesome.fa_suitcase, user.Occupation); + bottomLinkContainer.NewLine(); if (!string.IsNullOrEmpty(user.Twitter)) - tryAddInfoRightLine(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfoRightLine(FontAwesome.fa_gamepad, user.Discord); - tryAddInfoRightLine(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); - tryAddInfoRightLine(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfoRightLine(FontAwesome.fa_globe, websiteWithoutProtcol, user.Website); - - if (user.Statistics != null) - { - levelBadge.Show(); - levelText.Text = user.Statistics.Level.Current.ToString(); - - scoreText.Add(createScoreText("Ranked Score")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.RankedScore.ToString(@"#,0"))); - scoreText.Add(createScoreText("Accuracy")); - scoreNumberText.Add(createScoreNumberText($"{user.Statistics.Accuracy:0.##}%")); - scoreText.Add(createScoreText("Play Count")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.PlayCount.ToString(@"#,0"))); - scoreText.Add(createScoreText("Total Score")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.TotalScore.ToString(@"#,0"))); - scoreText.Add(createScoreText("Total Hits")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.TotalHits.ToString(@"#,0"))); - scoreText.Add(createScoreText("Max Combo")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.MaxCombo.ToString(@"#,0"))); - scoreText.Add(createScoreText("Replays Watched by Others")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.ReplaysWatched.ToString(@"#,0"))); - - gradeSSPlus.DisplayCount = user.Statistics.GradesCount.SSPlus; - gradeSSPlus.Show(); - gradeSS.DisplayCount = user.Statistics.GradesCount.SS; - gradeSS.Show(); - gradeSPlus.DisplayCount = user.Statistics.GradesCount.SPlus; - gradeSPlus.Show(); - gradeS.DisplayCount = user.Statistics.GradesCount.S; - gradeS.Show(); - gradeA.DisplayCount = user.Statistics.GradesCount.A; - gradeA.Show(); - - rankGraph.User.Value = user; - } - - badgeContainer.ShowBadges(user.Badges);*/ - } - - private class CoverInfoTabControl : TabControl - { - private readonly Box bar; - - private Color4 accentColour; - public Color4 AccentColour - { - get => accentColour; - set - { - if (accentColour == value) return; - - accentColour = value; - - bar.Colour = value; - - foreach (TabItem tabItem in TabContainer) - { - ((CoverInfoTabItem)tabItem).AccentColour = value; - } - } - } - - public MarginPadding Padding - { - set => TabContainer.Padding = value; - get => TabContainer.Padding; - } - - public CoverInfoTabControl() - { - TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(20, 0); - - AddInternal(bar = new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Anchor = Anchor.BottomLeft, - Origin = Anchor.CentreLeft - }); - } - - protected override Dropdown CreateDropdown() => null; - - protected override TabItem CreateTabItem(string value) => new CoverInfoTabItem(value) - { - AccentColour = AccentColour - }; - - private class CoverInfoTabItem : TabItem - { - private readonly OsuSpriteText text; - private readonly Drawable bar; - - private Color4 accentColour; - public Color4 AccentColour - { - get => accentColour; - set - { - accentColour = value; - - bar.Colour = value; - if (!Active) text.Colour = value; - } - } - - public CoverInfoTabItem(string value) - : base(value) - { - AutoSizeAxes = Axes.X; - RelativeSizeAxes = Axes.Y; - - Children = new[] - { - text = new OsuSpriteText - { - Margin = new MarginPadding { Bottom = 15 }, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Text = value, - TextSize = 14, - Font = "Exo2.0-Bold", - }, - bar = new Circle - { - RelativeSizeAxes = Axes.X, - Height = 0, - Origin = Anchor.CentreLeft, - Anchor = Anchor.BottomLeft, - }, - new HoverClickSounds() - }; - } - - protected override bool OnHover(HoverEvent e) - { - if (!Active) - onActivated(true); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - - if (!Active) - OnDeactivated(); - } - - protected override void OnActivated() - { - onActivated(); - } - - protected override void OnDeactivated() - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - bar.ResizeHeightTo(0, 120, Easing.InQuad); - text.Font = "Exo2.0-Medium"; - } - - private void onActivated(bool fake = false) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); - if (!fake) - text.Font = "Exo2.0-Bold"; - } - } + tryAddInfo(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); + tryAddInfo(FontAwesome.fa_gamepad, user.Discord); //todo: update fontawesome to include discord logo + tryAddInfo(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + tryAddInfo(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + tryAddInfo(FontAwesome.fa_link, websiteWithoutProtcol, user.Website); } private class UserStatsLine : Container @@ -1108,5 +1021,37 @@ namespace osu.Game.Overlays.Profile rankSprite.Texture = textures.Get($"Grades/{rank.GetDescription()}"); } } + + private class DrawableBadge : CompositeDrawable, IHasTooltip + { + public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); + + private readonly Badge badge; + + public DrawableBadge(Badge badge) + { + this.badge = badge; + Size = DRAWABLE_BADGE_SIZE; + } + + [BackgroundDependencyLoader] + private void load(LargeTextureStore textures) + { + InternalChild = new Sprite + { + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(badge.ImageUrl), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + InternalChild.FadeInFromZero(200); + } + + public string TooltipText => badge.Description; + } } } From da99161736610b1dba44962f8e03bd87a7efd462 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 22 Dec 2018 22:31:11 +0100 Subject: [PATCH 003/278] add some missing stuff --- osu.Game/Graphics/UserInterface/LineGraph.cs | 1 - .../Overlays/Profile/Header/SupporterIcon.cs | 1 - osu.Game/Overlays/Profile/ProfileHeader.cs | 44 ++++++++++++++++--- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index c750f7a89d..4948c0d7f4 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -111,7 +111,6 @@ namespace osu.Game.Graphics.UserInterface { float x = (i + count - values.Length) / (float)(count - 1) * DrawWidth - 1; float y = GetYPosition(values[i]) * DrawHeight - path.PathWidth; - // the -1 is for inner offset in path (actually -PathWidth) path.AddVertex(new Vector2(x, y)); } } diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs index 8b33a60d37..03135824de 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osuTK; namespace osu.Game.Overlays.Profile.Header { diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 6ab178cfe1..1a51ab4cb6 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions; @@ -39,6 +40,7 @@ namespace osu.Game.Overlays.Profile private readonly Box headerTopBox; private readonly UpdateableAvatar avatar; private readonly OsuSpriteText usernameText; + private readonly ExternalLinkButton openUserExternally; private readonly OsuSpriteText titleText; private readonly DrawableFlag userFlag; private readonly OsuSpriteText userCountryText; @@ -76,6 +78,13 @@ namespace osu.Game.Overlays.Profile private const float cover_height = 150; private const float cover_info_height = 75; private const float avatar_size = 110; + private static readonly Dictionary play_styles = new Dictionary + { + {"keyboard", "Keyboard"}, + {"mouse", "Mouse"}, + {"tablet", "Tablet"}, + {"touch", "Touch Screen"}, + }; [Resolved(CanBeNull = true)] private ChannelManager channelManager { get; set; } @@ -195,10 +204,24 @@ namespace osu.Game.Overlays.Profile Padding = new MarginPadding { Left = 10 }, Children = new Drawable[] { - usernameText = new OsuSpriteText + new FillFlowContainer { - Font = "Exo2.0-Regular", - TextSize = 24 + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + usernameText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 24 + }, + openUserExternally = new ExternalLinkButton + { + Margin = new MarginPadding { Left = 5 }, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + } }, new FillFlowContainer { @@ -694,6 +717,7 @@ namespace osu.Game.Overlays.Profile avatar.User = User; usernameText.Text = user.Username; + openUserExternally.Link = $@"https://osu.ppy.sh/users/{user.Id}"; userFlag.Country = user.Country; userCountryText.Text = user.Country?.FullName; SupporterTag.SupporterLevel = user.SupportLevel; @@ -796,16 +820,24 @@ namespace osu.Game.Overlays.Profile addSpacer(bottomTopLinkContainer); + if (user.PlayStyle?.Length > 0) + { + bottomTopLinkContainer.AddText("Plays with "); + bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyle.Select(style => play_styles[style])), bold); + + addSpacer(bottomTopLinkContainer); + } + if (user.LastVisit.HasValue) { bottomTopLinkContainer.AddText("Last seen "); bottomTopLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), bold); + + addSpacer(bottomTopLinkContainer); } - addSpacer(bottomTopLinkContainer); - bottomTopLinkContainer.AddText("Contributed "); - bottomTopLinkContainer.AddLink($@"{user.PostCount} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); + bottomTopLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); void tryAddInfo(FontAwesome icon, string content, string link = null) { From 360c17e2c76b43525f67b159ff5c3652248543e6 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 22 Dec 2018 22:50:19 +0100 Subject: [PATCH 004/278] appease CodeFactor and AppVeyor --- osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs | 2 +- osu.Game/Overlays/Profile/Header/RankGraph.cs | 6 ++---- osu.Game/Overlays/Profile/ProfileHeader.cs | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index b067273b04..2576d627ea 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; -namespace osu.Game.Overlays.Profile +namespace osu.Game.Overlays.Profile.Header { public class ProfileHeaderTabControl : TabControl { diff --git a/osu.Game/Overlays/Profile/Header/RankGraph.cs b/osu.Game/Overlays/Profile/Header/RankGraph.cs index f67a8e47d4..76a72fe420 100644 --- a/osu.Game/Overlays/Profile/Header/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/RankGraph.cs @@ -190,19 +190,17 @@ namespace osu.Game.Overlays.Profile.Header public string TooltipText => User.Value?.Statistics?.Ranks.Global == null ? "" : $"{ranks[dayIndex].Value:#,##0}|{ranked_days - ranks[dayIndex].Key + 1}"; - public ITooltip GetCustomTooltip() => new RankGraphTooltip(this); + public ITooltip GetCustomTooltip() => new RankGraphTooltip(); public class RankGraphTooltip : VisibilityContainer, ITooltip { - private readonly RankGraph graph; private readonly OsuSpriteText globalRankingText, timeText; private readonly Box background; public string TooltipText { get; set; } - public RankGraphTooltip(RankGraph graph) + public RankGraphTooltip() { - this.graph = graph; AutoSizeAxes = Axes.Both; Masking = true; CornerRadius = 10; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 1a51ab4cb6..77074abd09 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -353,7 +353,6 @@ namespace osu.Game.Overlays.Profile }, } }, - } }, new Container From e05fbd4136e338537e4ec6f9d64f958413b0f705 Mon Sep 17 00:00:00 2001 From: jorolf Date: Tue, 25 Dec 2018 01:09:49 +0100 Subject: [PATCH 005/278] address some comments and improve ui --- .../Overlays/Profile/Header/ProfileHeaderTabControl.cs | 2 +- osu.Game/Overlays/Profile/Header/RankGraph.cs | 2 ++ osu.Game/Overlays/Profile/ProfileHeader.cs | 10 +++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index 2576d627ea..db8a0b594c 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -38,8 +38,8 @@ namespace osu.Game.Overlays.Profile.Header public MarginPadding Padding { - set => TabContainer.Padding = value; get => TabContainer.Padding; + set => TabContainer.Padding = value; } public ProfileHeaderTabControl() diff --git a/osu.Game/Overlays/Profile/Header/RankGraph.cs b/osu.Game/Overlays/Profile/Header/RankGraph.cs index 76a72fe420..e681d2701a 100644 --- a/osu.Game/Overlays/Profile/Header/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/RankGraph.cs @@ -234,6 +234,8 @@ namespace osu.Game.Overlays.Profile.Header { Font = "Exo2.0-Regular", TextSize = 12, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, } } }, diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 77074abd09..7429a65210 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; using osu.Game.Online.Chat; using osu.Game.Overlays.Profile.Header; using osu.Game.Scoring; @@ -95,6 +96,9 @@ namespace osu.Game.Overlays.Profile [Resolved(CanBeNull = true)] private ChatOverlay chatOverlay { get; set; } + [Resolved] + private APIAccess apiAccess { get; set; } + public ProfileHeader() { Container expandedDetailContainer; @@ -340,6 +344,7 @@ namespace osu.Game.Overlays.Profile }, messageButton = new ProfileHeaderButton { + Alpha = 0, RelativeSizeAxes = Axes.Y, Children = new Drawable[] { @@ -734,13 +739,16 @@ namespace osu.Game.Overlays.Profile followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - if (!user.PMFriendsOnly) + if (!user.PMFriendsOnly && apiAccess.LocalUser.Value.Id != user.Id) + { + messageButton.Show(); messageButton.Action = () => { channelManager?.OpenPrivateChannel(user); userOverlay?.Hide(); chatOverlay?.Show(); }; + } expandButton.Action = DetailsVisible.Toggle; From a33a1458a58bc7f65eb281d06c9691316b0e308f Mon Sep 17 00:00:00 2001 From: jorolf Date: Fri, 4 Jan 2019 22:52:00 +0100 Subject: [PATCH 006/278] update design and make play styles an enum --- osu.Game/Overlays/Profile/ProfileHeader.cs | 24 ++++++++++----------- osu.Game/Users/User.cs | 25 ++++++++++++++++++++-- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 7429a65210..e6d892f0b7 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -75,6 +75,7 @@ namespace osu.Game.Overlays.Profile private readonly Box headerBottomBox; private readonly LinkFlowContainer bottomTopLinkContainer; private readonly LinkFlowContainer bottomLinkContainer; + private Color4 linkBlue; private const float cover_height = 150; private const float cover_info_height = 75; @@ -693,6 +694,7 @@ namespace osu.Game.Overlays.Profile headerBottomBox.Colour = colours.CommunityUserGrayGreenDarker; communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; + linkBlue = colours.BlueLight; } private User user; @@ -827,10 +829,10 @@ namespace osu.Game.Overlays.Profile addSpacer(bottomTopLinkContainer); - if (user.PlayStyle?.Length > 0) + if (user.PlayStyles?.Length > 0) { bottomTopLinkContainer.AddText("Plays with "); - bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyle.Select(style => play_styles[style])), bold); + bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), bold); addSpacer(bottomTopLinkContainer); } @@ -857,7 +859,11 @@ namespace osu.Game.Overlays.Profile }); if (link != null) { - bottomLinkContainer.AddLink(" " + content, link, creationParameters: bold); + bottomLinkContainer.AddLink(" " + content, link, creationParameters: text => + { + bold(text); + text.Colour = linkBlue; + }); } else { @@ -888,8 +894,6 @@ namespace osu.Game.Overlays.Profile private class UserStatsLine : Container { - private readonly OsuSpriteText rightText; - public UserStatsLine(string left, string right) { RelativeSizeAxes = Axes.X; @@ -902,22 +906,16 @@ namespace osu.Game.Overlays.Profile Text = left, Font = "Exo2.0-Medium" }, - rightText = new OsuSpriteText + new OsuSpriteText { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 15, Text = right, - Font = "Exo2.0-Medium" + Font = "Exo2.0-Bold" }, }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - rightText.Colour = colours.BlueLight; - } } private class ProfileHeaderButton : OsuHoverContainer diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 485c953b75..1005b094aa 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -2,7 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.ComponentModel; +using System.Linq; +using System.Security.Cryptography; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using osu.Framework.Configuration; namespace osu.Game.Users @@ -113,8 +117,13 @@ namespace osu.Game.Users [JsonProperty(@"follower_count")] public int[] FollowerCount; - [JsonProperty(@"playstyle")] - public string[] PlayStyle; + [JsonProperty] + private string[] playstyle + { + set { PlayStyles = value?.Select(str => Enum.Parse(typeof(PlayStyle), str, true)).Cast().ToArray(); } + } + + public PlayStyle[] PlayStyles; [JsonProperty(@"playmode")] public string PlayMode; @@ -174,5 +183,17 @@ namespace osu.Game.Users Username = "system", Id = 0 }; + + public enum PlayStyle + { + [Description("Keyboard")] + Keyboard, + [Description("Mouse")] + Mouse, + [Description("Tablet")] + Tablet, + [Description("Touch Screen")] + Touch, + } } } From 8bab87c072e96ef0ca2784d5ad6716ef7709994e Mon Sep 17 00:00:00 2001 From: jorolf Date: Fri, 4 Jan 2019 23:09:21 +0100 Subject: [PATCH 007/278] update resources and remove unused usings --- osu-resources | 2 +- osu.Game/Users/User.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu-resources b/osu-resources index 9880089b4e..677897728f 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 9880089b4e8fcd78d68f30c8a40d43bf8dccca86 +Subproject commit 677897728f4332fa1200e0280ca02c4b987c6c47 diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 1005b094aa..f90781df77 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -4,9 +4,7 @@ using System; using System.ComponentModel; using System.Linq; -using System.Security.Cryptography; using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using osu.Framework.Configuration; namespace osu.Game.Users From 6ba7e2b670da39a224b1ee9428553683485651a3 Mon Sep 17 00:00:00 2001 From: jorolf Date: Fri, 11 Jan 2019 01:12:19 +0100 Subject: [PATCH 008/278] split the profile header into several components --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 76 +- .../Visual/TestCaseUserProfileHeader.cs | 76 ++ .../Profile/Header/BottomHeaderContainer.cs | 160 ++++ .../Profile/Header/CenterHeaderContainer.cs | 321 +++++++ .../Profile/Header/DetailHeaderContainer.cs | 238 +++++ .../Profile/Header/MedalHeaderContainer.cs | 132 +++ .../Profile/Header/TopHeaderContainer.cs | 210 +++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 892 +----------------- 8 files changed, 1197 insertions(+), 908 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs create mode 100644 osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index cff55c2506..3753328427 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -32,6 +32,44 @@ namespace osu.Game.Tests.Visual typeof(SupporterIcon) }; + public static readonly User TEST_USER = new User + { + Username = @"Somebody", + Id = 1, + Country = new Country { FullName = @"Alien" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", + JoinDate = DateTimeOffset.Now.AddDays(-1), + LastVisit = DateTimeOffset.Now, + ProfileOrder = new[] { "me" }, + Statistics = new UserStatistics + { + Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, + PP = 4567.89m, + Level = new UserStatistics.LevelInfo + { + Current = 727, + Progress = 69, + } + }, + RankHistory = new User.RankHistoryData + { + Mode = @"osu", + Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + }, + Badges = new[] + { + new Badge + { + AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), + Description = "Outstanding help by being a voluntary test subject.", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" + } + }, + Title = "osu!volunteer", + Colour = "ff0000", + Achievements = new User.UserAchievement[0], + }; + public TestCaseUserProfile() { Add(profile = new TestUserProfileOverlay()); @@ -47,43 +85,7 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); - AddStep("Show offline dummy", () => profile.ShowUser(new User - { - Username = @"Somebody", - Id = 1, - Country = new Country { FullName = @"Alien" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", - JoinDate = DateTimeOffset.Now.AddDays(-1), - LastVisit = DateTimeOffset.Now, - ProfileOrder = new[] { "me" }, - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, - PP = 4567.89m, - Level = new UserStatistics.LevelInfo - { - Current = 727, - Progress = 69, - } - }, - RankHistory = new User.RankHistoryData - { - Mode = @"osu", - Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() - }, - Badges = new[] - { - new Badge - { - AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), - Description = "Outstanding help by being a voluntary test subject.", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" - } - }, - Title = "osu!volunteer", - Colour = "ff0000", - Achievements = new User.UserAchievement[0], - }, false)); + AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER, false)); checkSupporterTag(false); diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs new file mode 100644 index 0000000000..c80227f149 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs @@ -0,0 +1,76 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Profile; +using osu.Game.Overlays.Profile.Header; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseUserProfileHeader : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileHeader), + typeof(RankGraph), + typeof(LineGraph), + typeof(SupporterIcon) + }; + + [Resolved] + private APIAccess api { get; set; } + + private readonly ProfileHeader header; + + public TestCaseUserProfileHeader() + { + header = new ProfileHeader(); + Add(header); + + AddStep("Show offline dummy", () => header.User = TestCaseUserProfile.TEST_USER); + + AddStep("Show null dummy", () => header.User = new User + { + Username = "Null" + }); + + addOnlineStep("Show ppy", new User + { + Username = @"peppy", + Id = 2, + IsSupporter = true, + Country = new Country { FullName = @"Australia", FlagName = @"AU" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" + }); + + addOnlineStep("Show flyte", new User + { + Username = @"flyte", + Id = 3103765, + Country = new Country { FullName = @"Japan", FlagName = @"JP" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg" + }); + } + + private void addOnlineStep(string name, User fallback) + { + AddStep(name, () => + { + if (api.IsLoggedIn) + { + var request = new GetUserRequest(fallback.Id); + request.Success += user => header.User = user; + api.Queue(request); + } + else + header.User = fallback; + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs new file mode 100644 index 0000000000..a3a6447a9f --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -0,0 +1,160 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class BottomHeaderContainer : Container + { + private LinkFlowContainer bottomTopLinkContainer; + private LinkFlowContainer bottomLinkContainer; + private Color4 linkBlue, communityUserGrayGreenLighter; + + private User user; + public User User + { + get => user; + set + { + if (user == value) return; + user = value; + updateDisplay(); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.CommunityUserGrayGreenDarker, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + bottomTopLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + bottomLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } + } + }; + + linkBlue = colours.BlueLight; + communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; + } + + private void updateDisplay() + { + void bold(SpriteText t) => t.Font = @"Exo2.0-Bold"; + void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); + + bottomTopLinkContainer.Clear(); + bottomLinkContainer.Clear(); + + if (user == null) return; + + if (user.JoinDate.ToUniversalTime().Year < 2008) + { + bottomTopLinkContainer.AddText("Here since the beginning"); + } + else + { + bottomTopLinkContainer.AddText("Joined "); + bottomTopLinkContainer.AddText(new DrawableDate(user.JoinDate), bold); + } + + addSpacer(bottomTopLinkContainer); + + if (user.PlayStyles?.Length > 0) + { + bottomTopLinkContainer.AddText("Plays with "); + bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), bold); + + addSpacer(bottomTopLinkContainer); + } + + if (user.LastVisit.HasValue) + { + bottomTopLinkContainer.AddText("Last seen "); + bottomTopLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), bold); + + addSpacer(bottomTopLinkContainer); + } + + bottomTopLinkContainer.AddText("Contributed "); + bottomTopLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); + + void tryAddInfo(FontAwesome icon, string content, string link = null) + { + if (string.IsNullOrEmpty(content)) return; + + bottomLinkContainer.AddIcon(icon, text => + { + text.TextSize = 10; + text.Colour = communityUserGrayGreenLighter; + }); + if (link != null) + { + bottomLinkContainer.AddLink(" " + content, link, creationParameters: text => + { + bold(text); + text.Colour = linkBlue; + }); + } + else + { + bottomLinkContainer.AddText(" " + content, bold); + } + addSpacer(bottomLinkContainer); + } + + string websiteWithoutProtcol = user.Website; + if (!string.IsNullOrEmpty(websiteWithoutProtcol)) + { + int protocolIndex = websiteWithoutProtcol.IndexOf("//", StringComparison.Ordinal); + if (protocolIndex >= 0) + websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); + } + + tryAddInfo(FontAwesome.fa_map_marker, user.Location); + tryAddInfo(FontAwesome.fa_heart_o, user.Interests); + tryAddInfo(FontAwesome.fa_suitcase, user.Occupation); + bottomLinkContainer.NewLine(); + if (!string.IsNullOrEmpty(user.Twitter)) + tryAddInfo(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); + tryAddInfo(FontAwesome.fa_gamepad, user.Discord); //todo: update fontawesome to include discord logo + tryAddInfo(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + tryAddInfo(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + tryAddInfo(FontAwesome.fa_link, websiteWithoutProtcol, user.Website); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs new file mode 100644 index 0000000000..9005fd5ab2 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -0,0 +1,321 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.Chat; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class CenterHeaderContainer : Container + { + public readonly BindableBool DetailsVisible = new BindableBool(); + + private OsuSpriteText followerText; + private ProfileHeaderButton messageButton; + private OsuSpriteText levelBadgeText; + + private Bar levelProgressBar; + private OsuSpriteText levelProgressText; + + private ProfileHeader.OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; + + [Resolved(CanBeNull = true)] + private ChannelManager channelManager { get; set; } + + [Resolved(CanBeNull = true)] + private UserProfileOverlay userOverlay { get; set; } + + [Resolved(CanBeNull = true)] + private ChatOverlay chatOverlay { get; set; } + + [Resolved] + private APIAccess apiAccess { get; set; } + + private User user; + public User User + { + get => user; + set + { + if (user == value) return; + user = value; + updateDisplay(); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, TextureStore textures) + { + Container hiddenDetailContainer, expandedDetailContainer; + SpriteIcon expandButtonIcon; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.CommunityUserGrayGreenDark + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Vertical = 10 }, + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new ProfileHeaderButton + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Right = 10 }, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_user, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }, + followerText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 16, + Font = "Exo2.0-Bold" + } + } + } + } + }, + messageButton = new ProfileHeaderButton + { + Alpha = 0, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_envelope, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }, + } + }, + } + }, + new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Vertical = 10 }, + Width = UserProfileOverlay.CONTENT_X_MARGIN, + Child = new ProfileHeaderButton + { + RelativeSizeAxes = Axes.Y, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Action = DetailsVisible.Toggle, + Children = new Drawable[] + { + expandButtonIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20), + Icon = FontAwesome.fa_chevron_up, + }, + } + }, + }, + new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, + Children = new Drawable[] + { + new ProfileHeader.HasTooltipContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(40), + TooltipText = "Level", + Children = new Drawable[] + { + new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get("Profile/levelbadge"), + Colour = colours.Yellow, + }, + levelBadgeText = new OsuSpriteText + { + TextSize = 20, + Font = "Exo2.0-Medium", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + }, + expandedDetailContainer = new ProfileHeader.HasTooltipContainer + { + TooltipText = "Progress to next level", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Width = 200, + Height = 6, + Margin = new MarginPadding { Right = 50 }, + Children = new Drawable[] + { + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = levelProgressBar = new Bar + { + RelativeSizeAxes = Axes.Both, + BackgroundColour = Color4.Black, + Direction = BarDirection.LeftToRight, + AccentColour = colours.Yellow + } + }, + levelProgressText = new OsuSpriteText + { + Anchor = Anchor.BottomRight, + Origin = Anchor.TopRight, + Font = "Exo2.0-Bold", + TextSize = 12, + } + } + }, + hiddenDetailContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Width = 200, + AutoSizeAxes = Axes.Y, + Alpha = 0, + Spacing = new Vector2(10, 0), + Margin = new MarginPadding { Right = 50 }, + Children = new[] + { + hiddenDetailGlobal = new ProfileHeader.OverlinedInfoContainer + { + Title = "Global Ranking", + LineColour = colours.Yellow + }, + hiddenDetailCountry = new ProfileHeader.OverlinedInfoContainer + { + Title = "Country Ranking", + LineColour = colours.Yellow + }, + } + } + } + } + }; + + DetailsVisible.ValueChanged += newValue => expandButtonIcon.Icon = newValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; + DetailsVisible.ValueChanged += newValue => hiddenDetailContainer.Alpha = newValue ? 1 : 0; + DetailsVisible.ValueChanged += newValue => expandedDetailContainer.Alpha = newValue ? 0 : 1; + } + + private void updateDisplay() + { + followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; + + if (!user.PMFriendsOnly && apiAccess.LocalUser.Value.Id != user.Id) + { + messageButton.Show(); + messageButton.Action = () => + { + channelManager?.OpenPrivateChannel(user); + userOverlay?.Hide(); + chatOverlay?.Show(); + }; + } + else + { + messageButton.Hide(); + } + + levelBadgeText.Text = user.Statistics?.Level.Current.ToString() ?? "0"; + levelProgressBar.Length = user.Statistics?.Level.Progress / 100f ?? 0; + levelProgressText.Text = user.Statistics?.Level.Progress.ToString("0'%'"); + + hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; + hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; + + } + + private class ProfileHeaderButton : OsuHoverContainer + { + private readonly Box background; + private readonly Container content; + + protected override Container Content => content; + + protected override IEnumerable EffectTargets => new[] { background }; + + public ProfileHeaderButton() + { + HoverColour = Color4.Black.Opacity(0.75f); + IdleColour = Color4.Black.Opacity(0.7f); + AutoSizeAxes = Axes.X; + + base.Content.Add(new CircularContainer + { + Masking = true, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + content = new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 10 }, + } + } + }); + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs new file mode 100644 index 0000000000..678fc2ddb7 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -0,0 +1,238 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Scoring; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class DetailHeaderContainer : Container + { + private ProfileHeader.HasTooltipContainer totalPlayTimeTooltip; + private ProfileHeader.OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; + private readonly Dictionary scoreRankInfos = new Dictionary(); + private ProfileHeader.OverlinedInfoContainer detailGlobalRank, detailCountryRank; + private RankGraph rankGraph; + + private User user; + public User User + { + get => user; + set + { + if (user == value) return; + user = value; + updateDisplay(); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.CommunityUserGrayGreenDarkest, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + totalPlayTimeTooltip = new ProfileHeader.HasTooltipContainer + { + AutoSizeAxes = Axes.Both, + TooltipText = "0 hours", + Child = totalPlayTimeInfo = new ProfileHeader.OverlinedInfoContainer + { + Title = "Total Play Time", + LineColour = colours.Yellow, + }, + }, + medalInfo = new ProfileHeader.OverlinedInfoContainer + { + Title = "Medals", + LineColour = colours.GreenLight, + }, + ppInfo = new ProfileHeader.OverlinedInfoContainer + { + Title = "pp", + LineColour = colours.Red, + }, + } + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Children = new[] + { + scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), + scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), + scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), + scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), + scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = 130 }, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 130, + Anchor = Anchor.TopRight, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Horizontal = 10 }, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + detailGlobalRank = new ProfileHeader.OverlinedInfoContainer(true, 110) + { + Title = "Global Ranking", + LineColour = colours.Yellow, + }, + detailCountryRank = new ProfileHeader.OverlinedInfoContainer(false, 110) + { + Title = "Country Ranking", + LineColour = colours.Yellow, + }, + } + } + } + }, + } + }, + }; + } + + private void updateDisplay() + { + medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; + ppInfo.Content = user?.Statistics?.PP?.ToString("#,##0") ?? "0"; + + string formatTime(int? secondsNull) + { + if (secondsNull == null) return "0h 0m"; + + int seconds = secondsNull.Value; + string time = ""; + + int days = seconds / 86400; + seconds -= days * 86400; + if (days > 0) + time += days + "d "; + + int hours = seconds / 3600; + seconds -= hours * 3600; + time += hours + "h "; + + int minutes = seconds / 60; + time += minutes + "m"; + + return time; + } + + totalPlayTimeInfo.Content = formatTime(user?.Statistics?.PlayTime); + totalPlayTimeTooltip.TooltipText = (user?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; + + foreach (var scoreRankInfo in scoreRankInfos) + scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount.GetForScoreRank(scoreRankInfo.Key) ?? 0; + + detailGlobalRank.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; + detailCountryRank.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; + + rankGraph.User.Value = user; + } + + private class ScoreRankInfo : CompositeDrawable + { + private readonly ScoreRank rank; + private readonly Sprite rankSprite; + private readonly OsuSpriteText rankCount; + + public int RankCount + { + set => rankCount.Text = value.ToString("#,##0"); + } + + public ScoreRankInfo(ScoreRank rank) + { + this.rank = rank; + + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 56, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + rankSprite = new Sprite + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + }, + rankCount = new OsuSpriteText + { + Font = "Exo2.0-Bold", + TextSize = 12, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + rankSprite.Texture = textures.Get($"Grades/{rank.GetDescription()}"); + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs new file mode 100644 index 0000000000..74f1e2f689 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -0,0 +1,132 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class MedalHeaderContainer : Container + { + private FillFlowContainer badgeFlowContainer; + + private User user; + public User User + { + get => user; + set + { + if (user == value) return; + user = value; + updateDisplay(); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Alpha = 0; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.CommunityUserGrayGreenDarkest, + }, + new Container //artificial shadow + { + RelativeSizeAxes = Axes.X, + Height = 3, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = new ColourInfo + { + TopLeft = Color4.Black.Opacity(0.2f), + TopRight = Color4.Black.Opacity(0.2f), + BottomLeft = Color4.Black.Opacity(0), + BottomRight = Color4.Black.Opacity(0) + } + }, + }, + badgeFlowContainer = new FillFlowContainer + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5 }, + Spacing = new Vector2(10, 10), + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + } + }; + } + + private void updateDisplay() + { + var badges = User.Badges; + badgeFlowContainer.Clear(); + if (badges?.Length > 0) + { + Show(); + for (var index = 0; index < badges.Length; index++) + { + int displayIndex = index; + LoadComponentAsync(new DrawableBadge(badges[index]), asyncBadge => + { + badgeFlowContainer.Add(asyncBadge); + + // load in stable order regardless of async load order. + badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex); + }); + } + } + else + { + Hide(); + } + } + + private class DrawableBadge : CompositeDrawable, IHasTooltip + { + public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); + + private readonly Badge badge; + + public DrawableBadge(Badge badge) + { + this.badge = badge; + Size = DRAWABLE_BADGE_SIZE; + } + + [BackgroundDependencyLoader] + private void load(LargeTextureStore textures) + { + InternalChild = new Sprite + { + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(badge.ImageUrl), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + InternalChild.FadeInFromZero(200); + } + + public string TooltipText => badge.Description; + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs new file mode 100644 index 0000000000..b003f08b95 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -0,0 +1,210 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class TopHeaderContainer : Container + { + public SupporterIcon SupporterTag; + private UpdateableAvatar avatar; + private OsuSpriteText usernameText; + private ExternalLinkButton openUserExternally; + private OsuSpriteText titleText; + private DrawableFlag userFlag; + private OsuSpriteText userCountryText; + private FillFlowContainer userStats; + + private const float avatar_size = 110; + + private User user; + public User User + { + get => user; + set + { + if (user == value) return; + user = value; + updateDisplay(); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.CommunityUserGrayGreenDarker, + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Height = avatar_size, + AutoSizeAxes = Axes.X, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new[] + { + avatar = new UpdateableAvatar + { + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = avatar_size * 0.25f, + OpenOnClick = { Value = false }, + }, + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Left = 10 }, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + usernameText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 24 + }, + openUserExternally = new ExternalLinkButton + { + Margin = new MarginPadding { Left = 5 }, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + } + }, + new FillFlowContainer + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + titleText = new OsuSpriteText + { + TextSize = 18, + Font = "Exo2.0-Regular" + }, + SupporterTag = new SupporterIcon + { + Height = 20, + Margin = new MarginPadding { Top = 5 } + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 1.5f, + Margin = new MarginPadding { Top = 10 }, + Colour = colours.CommunityUserGrayGreenLighter, + }, + new Container + { + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 5 }, + Children = new Drawable[] + { + userFlag = new DrawableFlag + { + Size = new Vector2(30, 20) + }, + userCountryText = new OsuSpriteText + { + Font = "Exo2.0-Regular", + TextSize = 17.5f, + Margin = new MarginPadding { Left = 40 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Colour = colours.CommunityUserGrayGreenLighter, + } + } + }, + } + } + } + } + } + }, + userStats = new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Y, + Width = 300, + Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, + Padding = new MarginPadding { Vertical = 15 }, + Spacing = new Vector2(0, 2) + } + }; + } + + private void updateDisplay() + { + avatar.User = User; + usernameText.Text = user.Username; + openUserExternally.Link = $@"https://osu.ppy.sh/users/{user.Id}"; + userFlag.Country = user.Country; + userCountryText.Text = user.Country?.FullName ?? "Alien"; + SupporterTag.SupporterLevel = user.SupportLevel; + titleText.Text = user.Title; + titleText.Colour = OsuColour.FromHex(user.Colour ?? "fff"); + + userStats.Clear(); + if (user.Statistics != null) + { + userStats.Add(new UserStatsLine("Ranked Score", user.Statistics.RankedScore.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Hit Accuracy", Math.Round(user.Statistics.Accuracy, 2).ToString("#0.00'%'"))); + userStats.Add(new UserStatsLine("Play Count", user.Statistics.PlayCount.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Total Score", user.Statistics.TotalScore.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Total Hits", user.Statistics.TotalHits.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Maximum Combo", user.Statistics.MaxCombo.ToString("#,##0"))); + userStats.Add(new UserStatsLine("Replays Watched by Others", user.Statistics.ReplaysWatched.ToString("#,##0"))); + } + } + + private class UserStatsLine : Container + { + public UserStatsLine(string left, string right) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + new OsuSpriteText + { + TextSize = 15, + Text = left, + Font = "Exo2.0-Medium" + }, + new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + TextSize = 15, + Text = right, + Font = "Exo2.0-Bold" + }, + }; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index e6d892f0b7..8709640b48 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -1,12 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Extensions; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -14,91 +10,32 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.Chat; using osu.Game.Overlays.Profile.Header; -using osu.Game.Scoring; using osu.Game.Users; -using osuTK; namespace osu.Game.Overlays.Profile { public class ProfileHeader : Container { - private readonly RankGraph rankGraph; - - public readonly SupporterIcon SupporterTag; private readonly Container coverContainer; private readonly OsuSpriteText coverInfoText; private readonly ProfileHeaderTabControl infoTabControl; - private readonly Box headerTopBox; - private readonly UpdateableAvatar avatar; - private readonly OsuSpriteText usernameText; - private readonly ExternalLinkButton openUserExternally; - private readonly OsuSpriteText titleText; - private readonly DrawableFlag userFlag; - private readonly OsuSpriteText userCountryText; - private readonly Box userIconSeperatorBox; - private readonly FillFlowContainer userStats; - - private readonly Box headerCenterBox; - private readonly OsuSpriteText followerText; - private readonly ProfileHeaderButton messageButton; - private readonly ProfileHeaderButton expandButton; - private readonly Sprite levelBadgeSprite; - private readonly OsuSpriteText levelBadgeText; - - private readonly Bar levelProgressBar; - private readonly OsuSpriteText levelProgressText; - - private readonly OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; + private readonly TopHeaderContainer topHeaderContainer; + public SupporterIcon SupporterTag => topHeaderContainer.SupporterTag; + private readonly CenterHeaderContainer centerHeaderContainer; public readonly BindableBool DetailsVisible = new BindableBool(); - private readonly Box headerDetailBox; - private readonly HasTooltipContainer totalPlayTimeTooltip; - private readonly OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; - private readonly Dictionary scoreRankInfos = new Dictionary(); - private readonly OverlinedInfoContainer detailGlobalRank, detailCountryRank; - - private readonly Box headerBadgeBox; - private readonly FillFlowContainer badgeFlowContainer; - private readonly Container badgeContainer; - - private readonly Box headerBottomBox; - private readonly LinkFlowContainer bottomTopLinkContainer; - private readonly LinkFlowContainer bottomLinkContainer; - private Color4 linkBlue; + private readonly DetailHeaderContainer detailHeaderContainer; + private readonly MedalHeaderContainer medalHeaderContainer; + private readonly BottomHeaderContainer bottomHeaderContainer; private const float cover_height = 150; private const float cover_info_height = 75; - private const float avatar_size = 110; - private static readonly Dictionary play_styles = new Dictionary - { - {"keyboard", "Keyboard"}, - {"mouse", "Mouse"}, - {"tablet", "Tablet"}, - {"touch", "Touch Screen"}, - }; - - [Resolved(CanBeNull = true)] - private ChannelManager channelManager { get; set; } - - [Resolved(CanBeNull = true)] - private UserProfileOverlay userOverlay { get; set; } - - [Resolved(CanBeNull = true)] - private ChatOverlay chatOverlay { get; set; } - - [Resolved] - private APIAccess apiAccess { get; set; } public ProfileHeader() { @@ -175,478 +112,30 @@ namespace osu.Game.Overlays.Profile Direction = FillDirection.Vertical, Children = new Drawable[] { - new Container + topHeaderContainer = new TopHeaderContainer { RelativeSizeAxes = Axes.X, Height = 150, - Children = new Drawable[] - { - headerTopBox = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, - Height = avatar_size, - AutoSizeAxes = Axes.X, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Children = new[] - { - avatar = new UpdateableAvatar - { - Size = new Vector2(avatar_size), - Masking = true, - CornerRadius = avatar_size * 0.25f, - OpenOnClick = { Value = false }, - }, - new Container - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Padding = new MarginPadding { Left = 10 }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new Drawable[] - { - usernameText = new OsuSpriteText - { - Font = "Exo2.0-Regular", - TextSize = 24 - }, - openUserExternally = new ExternalLinkButton - { - Margin = new MarginPadding { Left = 5 }, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - }, - } - }, - new FillFlowContainer - { - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Vertical, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - titleText = new OsuSpriteText - { - TextSize = 18, - Font = "Exo2.0-Regular" - }, - SupporterTag = new SupporterIcon - { - Height = 20, - Margin = new MarginPadding { Top = 5 } - }, - userIconSeperatorBox = new Box - { - RelativeSizeAxes = Axes.X, - Height = 1.5f, - Margin = new MarginPadding { Top = 10 } - }, - new Container - { - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 5 }, - Children = new Drawable[] - { - userFlag = new DrawableFlag - { - Size = new Vector2(30, 20) - }, - userCountryText = new OsuSpriteText - { - Font = "Exo2.0-Regular", - TextSize = 17.5f, - Margin = new MarginPadding { Left = 40 }, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - } - } - }, - } - } - } - } - } - }, - userStats = new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Y, - Width = 300, - Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, - Padding = new MarginPadding { Vertical = 15 }, - Spacing = new Vector2(0, 2) - } - } }, - new Container + centerHeaderContainer = new CenterHeaderContainer { RelativeSizeAxes = Axes.X, Height = 60, - Children = new Drawable[] - { - headerCenterBox = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Padding = new MarginPadding { Vertical = 10 }, - Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new ProfileHeaderButton - { - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Padding = new MarginPadding { Right = 10 }, - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_user, - FillMode = FillMode.Fit, - Size = new Vector2(50, 14) - }, - followerText = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = 16, - Font = "Exo2.0-Bold" - } - } - } - } - }, - messageButton = new ProfileHeaderButton - { - Alpha = 0, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_envelope, - FillMode = FillMode.Fit, - Size = new Vector2(50, 14) - }, - } - }, - } - }, - new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Vertical = 10 }, - Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = expandButton = new ProfileHeaderButton - { - RelativeSizeAxes = Axes.Y, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] - { - expandButtonIcon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(20), - Icon = FontAwesome.fa_chevron_up, - }, - } - }, - }, - new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, - Children = new Drawable[] - { - new HasTooltipContainer - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Size = new Vector2(40), - TooltipText = "Level", - Children = new Drawable[] - { - levelBadgeSprite = new Sprite - { - RelativeSizeAxes = Axes.Both, - }, - levelBadgeText = new OsuSpriteText - { - TextSize = 20, - Font = "Exo2.0-Medium", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - } - }, - expandedDetailContainer = new HasTooltipContainer - { - TooltipText = "Progress to next level", - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Width = 200, - Height = 6, - Margin = new MarginPadding { Right = 50 }, - Children = new Drawable[] - { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = levelProgressBar = new Bar - { - RelativeSizeAxes = Axes.Both, - BackgroundColour = Color4.Black, - Direction = BarDirection.LeftToRight, - } - }, - levelProgressText = new OsuSpriteText - { - Anchor = Anchor.BottomRight, - Origin = Anchor.TopRight, - Font = "Exo2.0-Bold", - TextSize = 12, - } - } - }, - hiddenDetailContainer = new FillFlowContainer - { - Direction = FillDirection.Horizontal, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Width = 200, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Spacing = new Vector2(10, 0), - Margin = new MarginPadding { Right = 50 }, - Children = new[] - { - hiddenDetailGlobal = new OverlinedInfoContainer - { - Title = "Global Ranking" - }, - hiddenDetailCountry = new OverlinedInfoContainer - { - Title = "Country Ranking" - }, - } - } - } - } - } }, - new Container + detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - headerDetailBox = new Box - { - RelativeSizeAxes = Axes.Both, - }, - headerDetailContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - totalPlayTimeTooltip = new HasTooltipContainer - { - AutoSizeAxes = Axes.Both, - TooltipText = "0 hours", - Child = totalPlayTimeInfo = new OverlinedInfoContainer - { - Title = "Total Play Time", - }, - }, - medalInfo = new OverlinedInfoContainer - { - Title = "Medals" - }, - ppInfo = new OverlinedInfoContainer - { - Title = "pp" - }, - } - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Direction = FillDirection.Horizontal, - Children = new[] - { - scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), - scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), - scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), - scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), - scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), - } - } - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 130 }, - Children = new Drawable[] - { - rankGraph = new RankGraph - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 130, - Anchor = Anchor.TopRight, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 10 }, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - detailGlobalRank = new OverlinedInfoContainer(true, 110) - { - Title = "Global Ranking" - }, - detailCountryRank = new OverlinedInfoContainer(false, 110) - { - Title = "Country Ranking" - }, - } - } - } - }, - } - }, - } }, - badgeContainer = new Container + medalHeaderContainer = new MedalHeaderContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Alpha = 0, - Children = new Drawable[] - { - headerBadgeBox = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new Container //artificial shadow - { - RelativeSizeAxes = Axes.X, - Height = 3, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = new ColourInfo - { - TopLeft = Color4.Black.Opacity(0.2f), - TopRight = Color4.Black.Opacity(0.2f), - BottomLeft = Color4.Black.Opacity(0), - BottomRight = Color4.Black.Opacity(0) - } - }, - }, - badgeFlowContainer = new FillFlowContainer - { - Direction = FillDirection.Full, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5 }, - Spacing = new Vector2(10, 10), - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - } - } }, - new Container + bottomHeaderContainer = new BottomHeaderContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - headerBottomBox = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Spacing = new Vector2(0, 10), - Children = new Drawable[] - { - bottomTopLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - bottomLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - } - } - } - } }, } } @@ -655,46 +144,16 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Info"); infoTabControl.AddItem("Modding"); - DetailsVisible.ValueChanged += newValue => expandButtonIcon.Icon = newValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; - DetailsVisible.ValueChanged += newValue => hiddenDetailContainer.Alpha = newValue ? 1 : 0; - DetailsVisible.ValueChanged += newValue => expandedDetailContainer.Alpha = newValue ? 0 : 1; - DetailsVisible.ValueChanged += newValue => headerDetailContainer.Alpha = newValue ? 0 : 1; + centerHeaderContainer.DetailsVisible.BindTo(DetailsVisible); + DetailsVisible.ValueChanged += newValue => detailHeaderContainer.Alpha = newValue ? 0 : 1; } - private Color4 communityUserGrayGreenLighter; - - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures) { coverInfoText.Colour = colours.CommunityUserGreen; infoTabControl.AccentColour = colours.CommunityUserGreen; - - headerTopBox.Colour = colours.CommunityUserGrayGreenDarker; - userCountryText.Colour = colours.CommunityUserGrayGreenLighter; - userIconSeperatorBox.Colour = colours.CommunityUserGrayGreenLighter; - - headerCenterBox.Colour = colours.CommunityUserGrayGreenDark; - levelBadgeSprite.Texture = textures.Get("Profile/levelbadge"); - levelBadgeSprite.Colour = colours.Yellow; - levelProgressBar.AccentColour = colours.Yellow; - - hiddenDetailGlobal.LineColour = colours.Yellow; - hiddenDetailCountry.LineColour = colours.Yellow; - - headerDetailBox.Colour = colours.CommunityUserGrayGreenDarkest; - totalPlayTimeInfo.LineColour = colours.Yellow; - medalInfo.LineColour = colours.GreenLight; - ppInfo.LineColour = colours.Red; - - detailGlobalRank.LineColour = colours.Yellow; - detailCountryRank.LineColour = colours.Yellow; - - headerBadgeBox.Colour = colours.CommunityUserGrayGreenDarkest; - headerBottomBox.Colour = colours.CommunityUserGrayGreenDarker; - - communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; - linkBlue = colours.BlueLight; } private User user; @@ -704,13 +163,15 @@ namespace osu.Game.Overlays.Profile get => user; set { - user = value; - loadUser(); + medalHeaderContainer.User = detailHeaderContainer.User = bottomHeaderContainer.User = + centerHeaderContainer.User = topHeaderContainer.User = user = value; + updateDisplay(); } } - private void loadUser() + private void updateDisplay() { + coverContainer.RemoveAll(d => d is UserCoverBackground); LoadComponentAsync(new UserCoverBackground(user) { RelativeSizeAxes = Axes.Both, @@ -720,247 +181,14 @@ namespace osu.Game.Overlays.Profile OnLoadComplete = d => d.FadeInFromZero(200), Depth = float.MaxValue, }, coverContainer.Add); - - avatar.User = User; - usernameText.Text = user.Username; - openUserExternally.Link = $@"https://osu.ppy.sh/users/{user.Id}"; - userFlag.Country = user.Country; - userCountryText.Text = user.Country?.FullName; - SupporterTag.SupporterLevel = user.SupportLevel; - if(user.Title != null) - titleText.Text = user.Title; - titleText.Colour = OsuColour.FromHex(user.Colour ?? "fff"); - - userStats.Add(new UserStatsLine("Ranked Score", user.Statistics.RankedScore.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Hit Accuracy", Math.Round(user.Statistics.Accuracy, 2).ToString("#0.00'%'"))); - userStats.Add(new UserStatsLine("Play Count", user.Statistics.PlayCount.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Total Score", user.Statistics.TotalScore.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Total Hits", user.Statistics.TotalHits.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Maximum Combo", user.Statistics.MaxCombo.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Replays Watched by Others", user.Statistics.ReplaysWatched.ToString("#,##0"))); - - followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - - if (!user.PMFriendsOnly && apiAccess.LocalUser.Value.Id != user.Id) - { - messageButton.Show(); - messageButton.Action = () => - { - channelManager?.OpenPrivateChannel(user); - userOverlay?.Hide(); - chatOverlay?.Show(); - }; - } - - expandButton.Action = DetailsVisible.Toggle; - - levelBadgeText.Text = user.Statistics.Level.Current.ToString(); - levelProgressBar.Length = user.Statistics.Level.Progress / 100f; - levelProgressText.Text = user.Statistics.Level.Progress.ToString("0'%'"); - - hiddenDetailGlobal.Content = user.Statistics.Ranks.Global?.ToString("#,##0") ?? "-"; - hiddenDetailCountry.Content = user.Statistics.Ranks.Country?.ToString("#,##0") ?? "-"; - - medalInfo.Content = user.Achievements.Length.ToString(); - ppInfo.Content = user.Statistics.PP?.ToString("#,##0") ?? "0"; - - string formatTime(int? secondsNull) - { - if (secondsNull == null) return "0h 0m"; - - int seconds = secondsNull.Value; - string time = ""; - - int days = seconds / 86400; - seconds -= days * 86400; - if (days > 0) - time += days + "d "; - - int hours = seconds / 3600; - seconds -= hours * 3600; - time += hours + "h "; - - int minutes = seconds / 60; - time += minutes + "m"; - - return time; - } - - totalPlayTimeInfo.Content = formatTime(user.Statistics.PlayTime); - totalPlayTimeTooltip.TooltipText = (user.Statistics.PlayTime ?? 0) / 3600 + " hours"; - - foreach (var scoreRankInfo in scoreRankInfos) - scoreRankInfo.Value.RankCount = user.Statistics.GradesCount.GetForScoreRank(scoreRankInfo.Key); - - detailGlobalRank.Content = user.Statistics.Ranks.Global?.ToString("#,##0") ?? "-"; - detailCountryRank.Content = user.Statistics.Ranks.Country?.ToString("#,##0") ?? "-"; - - rankGraph.User.Value = user; - - var badges = User.Badges; - if (badges.Length > 0) - { - badgeContainer.Show(); - for (var index = 0; index < badges.Length; index++) - { - int displayIndex = index; - LoadComponentAsync(new DrawableBadge(badges[index]), asyncBadge => - { - badgeFlowContainer.Add(asyncBadge); - - // load in stable order regardless of async load order. - badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex); - }); - } - } - - void bold(SpriteText t) => t.Font = @"Exo2.0-Bold"; - void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); - - if (user.JoinDate.ToUniversalTime().Year < 2008) - { - bottomTopLinkContainer.AddText("Here since the beginning"); - } - else - { - bottomTopLinkContainer.AddText("Joined "); - bottomTopLinkContainer.AddText(new DrawableDate(user.JoinDate), bold); - } - - addSpacer(bottomTopLinkContainer); - - if (user.PlayStyles?.Length > 0) - { - bottomTopLinkContainer.AddText("Plays with "); - bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), bold); - - addSpacer(bottomTopLinkContainer); - } - - if (user.LastVisit.HasValue) - { - bottomTopLinkContainer.AddText("Last seen "); - bottomTopLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), bold); - - addSpacer(bottomTopLinkContainer); - } - - bottomTopLinkContainer.AddText("Contributed "); - bottomTopLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); - - void tryAddInfo(FontAwesome icon, string content, string link = null) - { - if (string.IsNullOrEmpty(content)) return; - - bottomLinkContainer.AddIcon(icon, text => - { - text.TextSize = 10; - text.Colour = communityUserGrayGreenLighter; - }); - if (link != null) - { - bottomLinkContainer.AddLink(" " + content, link, creationParameters: text => - { - bold(text); - text.Colour = linkBlue; - }); - } - else - { - bottomLinkContainer.AddText(" " + content, bold); - } - addSpacer(bottomLinkContainer); - } - - string websiteWithoutProtcol = user.Website; - if (!string.IsNullOrEmpty(websiteWithoutProtcol)) - { - int protocolIndex = websiteWithoutProtcol.IndexOf("//", StringComparison.Ordinal); - if (protocolIndex >= 0) - websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); - } - - tryAddInfo(FontAwesome.fa_map_marker, user.Location); - tryAddInfo(FontAwesome.fa_heart_o, user.Interests); - tryAddInfo(FontAwesome.fa_suitcase, user.Occupation); - bottomLinkContainer.NewLine(); - if (!string.IsNullOrEmpty(user.Twitter)) - tryAddInfo(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfo(FontAwesome.fa_gamepad, user.Discord); //todo: update fontawesome to include discord logo - tryAddInfo(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); - tryAddInfo(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfo(FontAwesome.fa_link, websiteWithoutProtcol, user.Website); } - private class UserStatsLine : Container - { - public UserStatsLine(string left, string right) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - new OsuSpriteText - { - TextSize = 15, - Text = left, - Font = "Exo2.0-Medium" - }, - new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - TextSize = 15, - Text = right, - Font = "Exo2.0-Bold" - }, - }; - } - } - - private class ProfileHeaderButton : OsuHoverContainer - { - private readonly Box background; - private readonly Container content; - - protected override Container Content => content; - - protected override IEnumerable EffectTargets => new[] { background }; - - public ProfileHeaderButton() - { - HoverColour = Color4.Black.Opacity(0.75f); - IdleColour = Color4.Black.Opacity(0.7f); - AutoSizeAxes = Axes.X; - - base.Content.Add(new CircularContainer - { - Masking = true, - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - content = new Container - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 10 }, - } - } - }); - } - } - - private class HasTooltipContainer : Container, IHasTooltip + public class HasTooltipContainer : Container, IHasTooltip { public string TooltipText { get; set; } } - private class OverlinedInfoContainer : CompositeDrawable + public class OverlinedInfoContainer : CompositeDrawable { private readonly Circle line; private readonly OsuSpriteText title, content; @@ -1012,83 +240,5 @@ namespace osu.Game.Overlays.Profile }; } } - - public class ScoreRankInfo : CompositeDrawable - { - private readonly ScoreRank rank; - private readonly Sprite rankSprite; - private readonly OsuSpriteText rankCount; - - public int RankCount - { - set => rankCount.Text = value.ToString("#,##0"); - } - - public ScoreRankInfo(ScoreRank rank) - { - this.rank = rank; - - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 56, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - rankSprite = new Sprite - { - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit - }, - rankCount = new OsuSpriteText - { - Font = "Exo2.0-Bold", - TextSize = 12, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - rankSprite.Texture = textures.Get($"Grades/{rank.GetDescription()}"); - } - } - - private class DrawableBadge : CompositeDrawable, IHasTooltip - { - public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); - - private readonly Badge badge; - - public DrawableBadge(Badge badge) - { - this.badge = badge; - Size = DRAWABLE_BADGE_SIZE; - } - - [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) - { - InternalChild = new Sprite - { - FillMode = FillMode.Fit, - RelativeSizeAxes = Axes.Both, - Texture = textures.Get(badge.ImageUrl), - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - InternalChild.FadeInFromZero(200); - } - - public string TooltipText => badge.Description; - } } } From 14d2ed7085a82ab9ba5d6c91a2aefd6cec4b9471 Mon Sep 17 00:00:00 2001 From: jorolf Date: Tue, 22 Jan 2019 19:50:42 +0100 Subject: [PATCH 009/278] fix codefactor issue that I didn't notice and has been there for 12 days --- osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index 9005fd5ab2..9be1eb4326 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -278,7 +278,6 @@ namespace osu.Game.Overlays.Profile.Header hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; - } private class ProfileHeaderButton : OsuHoverContainer From 481f33d17be543c6cef45f5d9e4875cde2e94432 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 23 Jan 2019 14:27:34 +0100 Subject: [PATCH 010/278] add setting to toggle the gameplay cursor trail --- .../Configuration/OsuConfigManager.cs | 4 +++- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs | 12 +++++++++++- osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs | 5 +++++ osu.Game/Configuration/GameConfigManager.cs | 5 ----- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs index 4fa49faf1d..492cc7cc7f 100644 --- a/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs +++ b/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs @@ -19,12 +19,14 @@ namespace osu.Game.Rulesets.Osu.Configuration Set(OsuSetting.SnakingInSliders, true); Set(OsuSetting.SnakingOutSliders, true); + Set(OsuSetting.ShowCursorTrail, true); } } public enum OsuSetting { SnakingInSliders, - SnakingOutSliders + SnakingOutSliders, + ShowCursorTrail } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index 582b99af7c..cf6ae2ad3d 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -23,6 +24,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor protected override Container Content => fadeContainer; + private Bindable showTrail; + private readonly CursorTrail cursorTrail; private readonly Container fadeContainer; public GameplayCursor() @@ -32,11 +35,18 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new CursorTrail { Depth = 1 } + cursorTrail = new CursorTrail { Depth = 1 } } }; } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + showTrail = config.GetBindable(OsuSetting.ShowCursorTrail); + showTrail.ValueChanged += v => cursorTrail.Alpha = v ? 1 : 0; + } + private int downCount; private void updateExpandedState() diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 9aa0f4101d..12ef66fa25 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -34,6 +34,11 @@ namespace osu.Game.Rulesets.Osu.UI LabelText = "Snaking out sliders", Bindable = config.GetBindable(OsuSetting.SnakingOutSliders) }, + new SettingsCheckbox + { + LabelText = "Show cursor trail", + Bindable = config.GetBindable(OsuSetting.ShowCursorTrail) + }, }; } } diff --git a/osu.Game/Configuration/GameConfigManager.cs b/osu.Game/Configuration/GameConfigManager.cs index 736273dc35..b2f2a8e971 100644 --- a/osu.Game/Configuration/GameConfigManager.cs +++ b/osu.Game/Configuration/GameConfigManager.cs @@ -72,9 +72,6 @@ namespace osu.Game.Configuration Set(GameSetting.MenuParallax, true); - Set(GameSetting.SnakingInSliders, true); - Set(GameSetting.SnakingOutSliders, true); - // Gameplay Set(GameSetting.DimLevel, 0.3, 0, 1, 0.01); Set(GameSetting.BlurLevel, 0, 0, 1, 0.01); @@ -150,8 +147,6 @@ namespace osu.Game.Configuration DisplayStarsMinimum, DisplayStarsMaximum, RandomSelectAlgorithm, - SnakingInSliders, - SnakingOutSliders, ShowFpsDisplay, ChatDisplayHeight, Version, From 3e936d386d6975984942e0862b766b0d161b12ec Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 23 Jan 2019 14:54:03 +0100 Subject: [PATCH 011/278] add missing dependency --- osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs index 472da88e1f..b24abc3d0a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Cursor; +using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Tests.Visual; @@ -20,6 +21,16 @@ namespace osu.Game.Rulesets.Osu.Tests public override IReadOnlyList RequiredTypes => new [] { typeof(CursorTrail) }; + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + + var configCache = dependencies.Get(); + dependencies.CacheAs((OsuConfigManager)configCache.GetConfigFor(new OsuRuleset())); + + return dependencies; + } + public CursorContainer Cursor => cursor; public bool ProvidingUserCursor => true; From 92edafc44a370ad4bdc4312c70190319a1aca3dc Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 23 Jan 2019 15:01:35 +0100 Subject: [PATCH 012/278] yeet whitespace --- osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs index b24abc3d0a..89b62116c5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests return dependencies; } - + public CursorContainer Cursor => cursor; public bool ProvidingUserCursor => true; From 648ed0e4677356a2b07721696ee3eece95fbe8af Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 27 Jan 2019 23:45:00 +0100 Subject: [PATCH 013/278] update license headers --- osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs | 4 ++-- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs | 4 ++-- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs index c80227f149..6f164890f9 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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; using System.Collections.Generic; diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index a3a6447a9f..df0409272f 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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; using System.Linq; diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index 9be1eb4326..30671487d3 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.Collections.Generic; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 678fc2ddb7..124299b0ba 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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.Collections.Generic; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 74f1e2f689..5a54270b80 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index db8a0b594c..fd7124f20f 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index b003f08b95..4186d08729 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/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; using osu.Framework.Allocation; From 559960036e61edf1caefb5670fe9c939dad0ef59 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 5 Feb 2019 14:48:35 +0300 Subject: [PATCH 014/278] update top score design --- .../Graphics/Containers/OsuHoverContainer.cs | 10 +- .../BeatmapSet/Scores/ClickableUsername.cs | 15 +- .../BeatmapSet/Scores/DrawableScore.cs | 16 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 422 ++++++++++++------ .../BeatmapSet/Scores/ScoresContainer.cs | 7 + 5 files changed, 328 insertions(+), 142 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index 276b0f9dd1..091499b7cd 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -1,12 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; -using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Input.Events; +using osuTK.Graphics; +using System.Collections.Generic; namespace osu.Game.Graphics.Containers { @@ -16,17 +16,19 @@ namespace osu.Game.Graphics.Containers protected Color4 IdleColour = Color4.White; + protected const float FADE_DURATION = 500; + protected virtual IEnumerable EffectTargets => new[] { Content }; protected override bool OnHover(HoverEvent e) { - EffectTargets.ForEach(d => d.FadeColour(HoverColour, 500, Easing.OutQuint)); + EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint)); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - EffectTargets.ForEach(d => d.FadeColour(IdleColour, 500, Easing.OutQuint)); + EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint)); base.OnHoverLost(e); } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs index 0eb8b325d3..e2aade986d 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs @@ -3,16 +3,20 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Users; +using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { public class ClickableUsername : OsuHoverContainer { - private readonly OsuSpriteText text; + private readonly SpriteText text; + protected override IEnumerable EffectTargets => new[] { text }; + private UserProfileOverlay profile; private User user; @@ -24,7 +28,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (user == value) return; user = value; - text.Text = user.Username; + OnUserUpdate(user); } } @@ -41,12 +45,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public ClickableUsername() { AutoSizeAxes = Axes.Both; - Child = text = new OsuSpriteText + Child = text = new SpriteText { Font = @"Exo2.0-BoldItalic", }; } + protected virtual void OnUserUpdate(User user) + { + text.Text = user.Username; + } + [BackgroundDependencyLoader(true)] private void load(UserProfileOverlay profile) { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 1f50385adc..609524f170 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,6 +15,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Users; +using osuTK; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -56,13 +56,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Size = new Vector2(30, 20), Margin = new MarginPadding { Left = 60 } }, - new ClickableUsername - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - User = score.User, - Margin = new MarginPadding { Left = 100 } - }, + //new ClickableUsername + //{ + // Anchor = Anchor.CentreLeft, + // Origin = Anchor.CentreLeft, + // User = score.User, + // Margin = new MarginPadding { Left = 100 } + //}, modsContainer = new ScoreModsContainer { Anchor = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index c9551cf6f8..2e2bb78634 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -1,13 +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 osuTK; -using osuTK.Graphics; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -19,29 +19,38 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Users; +using osuTK; +using osuTK.Graphics; +using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { public class DrawableTopScore : Container { private const float fade_duration = 100; - private const float height = 200; + private const float height = 100; private const float avatar_size = 80; private const float margin = 10; private readonly Box background; - private readonly Box bottomBackground; - private readonly Box middleLine; private readonly UpdateableAvatar avatar; private readonly DrawableFlag flag; private readonly ClickableUsername username; - private readonly OsuSpriteText rankText; - private readonly OsuSpriteText date; + private readonly SpriteText rankText; + private readonly SpriteText date; private readonly DrawableRank rank; - private readonly InfoColumn totalScore; - private readonly InfoColumn accuracy; - private readonly InfoColumn statistics; - private readonly ScoreModsContainer modsContainer; + + private readonly AutoSizeInfoColumn totalScore; + private readonly MediumInfoColumn accuracy; + private readonly MediumInfoColumn maxCombo; + + private readonly SmallInfoColumn hitGreat; + private readonly SmallInfoColumn hitGood; + private readonly SmallInfoColumn hitMeh; + private readonly SmallInfoColumn hitMiss; + private readonly SmallInfoColumn pp; + + private readonly ModsInfoColumn modsInfo; private APIScoreInfo score; public APIScoreInfo Score @@ -54,153 +63,296 @@ namespace osu.Game.Overlays.BeatmapSet.Scores avatar.User = username.User = score.User; flag.Country = score.User.Country; - date.Text = $@"achieved {score.Date:MMM d, yyyy}"; + date.Text = $@"achieved {score.Date.Humanize()}"; rank.UpdateRank(score.Rank); totalScore.Value = $@"{score.TotalScore:N0}"; accuracy.Value = $@"{score.Accuracy:P2}"; - statistics.Value = $"{score.Statistics[HitResult.Great]}/{score.Statistics[HitResult.Good]}/{score.Statistics[HitResult.Meh]}"; + maxCombo.Value = $@"{score.MaxCombo:N0}x"; - modsContainer.Clear(); - foreach (Mod mod in score.Mods) - modsContainer.Add(new ModIcon(mod) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.45f), - }); + hitGreat.Value = $"{score.Statistics[HitResult.Great]}"; + hitGood.Value = $"{score.Statistics[HitResult.Good]}"; + hitMeh.Value = $"{score.Statistics[HitResult.Meh]}"; + hitMiss.Value = $"{score.Statistics[HitResult.Miss]}"; + pp.Value = $@"{score.PP:N0}"; + + modsInfo.ClearMods(); + modsInfo.Mods = score.Mods; } } public DrawableTopScore() { RelativeSizeAxes = Axes.X; - Height = height; - CornerRadius = 5; - BorderThickness = 4; + AutoSizeAxes = Axes.Y; + CornerRadius = 3; Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Radius = 1, + Offset = new Vector2(0, 1), + }; Children = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, //used for correct border representation - }, - avatar = new UpdateableAvatar - { - Size = new Vector2(avatar_size), - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Offset = new Vector2(0, 2), - Radius = 1, - }, - Margin = new MarginPadding { Top = margin, Left = margin } - }, - flag = new DrawableFlag - { - Size = new Vector2(30, 20), - Position = new Vector2(margin * 2 + avatar_size, height / 4), - }, - username = new ClickableUsername - { - Origin = Anchor.BottomLeft, - TextSize = 30, - Position = new Vector2(margin * 2 + avatar_size, height / 4), - Margin = new MarginPadding { Bottom = 4 } - }, - rankText = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.BottomRight, - Text = "#1", - TextSize = 40, - Font = @"Exo2.0-BoldItalic", - Y = height / 4, - Margin = new MarginPadding { Right = margin } - }, - date = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Y = height / 4, - Margin = new MarginPadding { Right = margin } + Colour = Color4.White, }, new Container { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - Height = 0.5f, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(margin), Children = new Drawable[] { - bottomBackground = new Box { RelativeSizeAxes = Axes.Both }, - middleLine = new Box + new FillFlowContainer { - RelativeSizeAxes = Axes.X, - Height = 1, - }, - rank = new DrawableRank(ScoreRank.F) - { - Origin = Anchor.BottomLeft, - Size = new Vector2(avatar_size, 40), - FillMode = FillMode.Fit, - Y = height / 4, - Margin = new MarginPadding { Left = margin } - }, - new FillFlowContainer - { - Origin = Anchor.BottomLeft, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Position = new Vector2(height / 2, height / 4), Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), - Children = new[] + Spacing = new Vector2(margin, 0), + Children = new Drawable[] { - totalScore = new InfoColumn("Score"), - accuracy = new InfoColumn("Accuracy"), - statistics = new InfoColumn("300/100/50"), - }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + rankText = new SpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Text = "#1", + TextSize = 20, + Font = @"Exo2.0-BoldItalic", + }, + rank = new DrawableRank(ScoreRank.F) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(30), + FillMode = FillMode.Fit, + }, + } + }, + avatar = new UpdateableAvatar + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = 5, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.25f), + Offset = new Vector2(0, 2), + Radius = 1, + }, + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 3), + Children = new Drawable[] + { + username = new ClickableTopScoreUsername + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 20, + }, + date = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 10, + }, + flag = new DrawableFlag + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20, 13), + }, + } + } + } }, - modsContainer = new ScoreModsContainer + new Container { - AutoSizeAxes = Axes.Y, - Width = 80, - Position = new Vector2(height / 2, height / 4), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + totalScore = new AutoSizeInfoColumn("Total Score"), + accuracy = new MediumInfoColumn("Accuracy"), + maxCombo = new MediumInfoColumn("Max Combo"), + hitGreat = new SmallInfoColumn("300", 20), + hitGood = new SmallInfoColumn("100", 20), + hitMeh = new SmallInfoColumn("50", 20), + hitMiss = new SmallInfoColumn("miss", 20), + pp = new SmallInfoColumn("pp", 20), + modsInfo = new ModsInfoColumn("mods"), + } + } } } - }, + } }; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = bottomBackground.Colour = colours.Gray4; - middleLine.Colour = colours.Gray2; - date.Colour = colours.Gray9; - BorderColour = rankText.Colour = colours.Yellow; + date.Colour = rankText.Colour = colours.ContextMenuGray; } protected override bool OnHover(HoverEvent e) { - background.FadeIn(fade_duration, Easing.OutQuint); + background.FadeColour(Color4.WhiteSmoke, fade_duration, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - background.FadeOut(fade_duration, Easing.OutQuint); + background.FadeColour(Color4.White, fade_duration, Easing.OutQuint); base.OnHoverLost(e); } - private class InfoColumn : FillFlowContainer + private class ClickableTopScoreUsername : ClickableUsername { - private readonly OsuSpriteText headerText; - private readonly OsuSpriteText valueText; + private Box underscore; + + public ClickableTopScoreUsername() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 1, + Position = new Vector2(0, TextSize / 2 + 1.5f), + Depth = 1, + Child = underscore = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IdleColour = colours.ContextMenuGray; + HoverColour = underscore.Colour = colours.Blue; + } + + protected override bool OnHover(HoverEvent e) + { + underscore.FadeIn(FADE_DURATION, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + underscore.FadeOut(FADE_DURATION, Easing.OutQuint); + base.OnHoverLost(e); + } + } + + private class DrawableInfoColumn : FillFlowContainer + { + private readonly SpriteText headerText; + private const float header_text_size = 12; + + public DrawableInfoColumn(string header) + { + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + Spacing = new Vector2(0, 2); + Children = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + Height = header_text_size, + Child = headerText = new SpriteText + { + TextSize = 12, + Text = header.ToUpper(), + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 3, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.LightGray, + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + headerText.Colour = colours.ContextMenuGray; + } + } + + private class ModsInfoColumn : DrawableInfoColumn + { + private readonly FillFlowContainer modsContainer; + + public IEnumerable Mods + { + set + { + foreach (Mod mod in value) + modsContainer.Add(new ModIcon(mod) + { + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f), + }); + } + } + + public ModsInfoColumn(string header) : base(header) + { + AutoSizeAxes = Axes.Both; + Add(modsContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + }); + } + + public void ClearMods() => modsContainer.Clear(); + } + + private class TextInfoColumn : DrawableInfoColumn + { + private readonly SpriteText valueText; public string Value { @@ -213,31 +365,47 @@ namespace osu.Game.Overlays.BeatmapSet.Scores get { return valueText.Text; } } - public InfoColumn(string header) + public TextInfoColumn(string header, float valueTextSize = 25) : base(header) { - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Vertical; - Spacing = new Vector2(0, 3); - Children = new Drawable[] + Add(valueText = new SpriteText { - headerText = new OsuSpriteText - { - TextSize = 14, - Text = header, - Font = @"Exo2.0-Bold", - }, - valueText = new OsuSpriteText - { - TextSize = 25, - Font = @"Exo2.0-RegularItalic", - } - }; + TextSize = valueTextSize, + Font = @"Exo2.0-Light", + }); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - headerText.Colour = colours.Gray9; + valueText.Colour = colours.ContextMenuGray; + } + } + + private class AutoSizeInfoColumn : TextInfoColumn + { + public AutoSizeInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + { + AutoSizeAxes = Axes.Both; + } + } + + private class MediumInfoColumn : TextInfoColumn + { + private const float width = 70; + + public MediumInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + { + Width = width; + } + } + + private class SmallInfoColumn : TextInfoColumn + { + private const float width = 40; + + public SmallInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + { + Width = width; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index ab34d2ba1d..ac3068c2c8 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -12,6 +12,8 @@ using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -98,6 +100,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores AutoSizeAxes = Axes.Y; Children = new Drawable[] { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, new FillFlowContainer { Anchor = Anchor.TopCentre, From f560dde157acd3bb83cf417fd6d10a8d67088576 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 5 Feb 2019 15:26:45 +0300 Subject: [PATCH 015/278] Add some flow for info containers --- .../BeatmapSet/Scores/DrawableTopScore.cs | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 2e2bb78634..d061e176e0 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -193,23 +193,49 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Width = 0.7f, Child = new FillFlowContainer { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Spacing = new Vector2(margin), Children = new Drawable[] { - totalScore = new AutoSizeInfoColumn("Total Score"), - accuracy = new MediumInfoColumn("Accuracy"), - maxCombo = new MediumInfoColumn("Max Combo"), - hitGreat = new SmallInfoColumn("300", 20), - hitGood = new SmallInfoColumn("100", 20), - hitMeh = new SmallInfoColumn("50", 20), - hitMiss = new SmallInfoColumn("miss", 20), - pp = new SmallInfoColumn("pp", 20), - modsInfo = new ModsInfoColumn("mods"), + new FillFlowContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + hitGreat = new SmallInfoColumn("300", 20), + hitGood = new SmallInfoColumn("100", 20), + hitMeh = new SmallInfoColumn("50", 20), + hitMiss = new SmallInfoColumn("miss", 20), + pp = new SmallInfoColumn("pp", 20), + modsInfo = new ModsInfoColumn("mods"), + } + }, + new FillFlowContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + totalScore = new AutoSizeInfoColumn("Total Score"), + accuracy = new MediumInfoColumn("Accuracy"), + maxCombo = new MediumInfoColumn("Max Combo"), + } + }, } } } @@ -248,7 +274,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, Height = 1, - Position = new Vector2(0, TextSize / 2 + 1.5f), + Position = new Vector2(0, TextSize / 2 - 1), Depth = 1, Child = underscore = new Box { From c85dc1a2362434298d57661f4cd87e8f71f4e049 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Tue, 5 Feb 2019 19:32:33 +0300 Subject: [PATCH 016/278] update another scores design --- .../Visual/TestCaseBeatmapSetOverlay.cs | 8 +- ...eUsername.cs => ClickableUserContainer.cs} | 29 +- .../BeatmapSet/Scores/DrawableScore.cs | 278 ++++++++++++++---- .../BeatmapSet/Scores/DrawableTopScore.cs | 46 ++- .../BeatmapSet/Scores/ScoreTextLine.cs | 118 ++++++++ .../BeatmapSet/Scores/ScoresContainer.cs | 18 +- 6 files changed, 397 insertions(+), 100 deletions(-) rename osu.Game/Overlays/BeatmapSet/Scores/{ClickableUsername.cs => ClickableUserContainer.cs} (60%) create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs index b98014b866..20609dc595 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; @@ -13,6 +10,9 @@ using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets; using osu.Game.Users; +using System; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Tests.Visual { @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(Header), - typeof(ClickableUsername), + typeof(ClickableUserContainer), typeof(DrawableScore), typeof(DrawableTopScore), typeof(ScoresContainer), diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs similarity index 60% rename from osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs rename to osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs index e2aade986d..2f402bfa74 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUsername.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; @@ -12,11 +13,8 @@ using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ClickableUsername : OsuHoverContainer + public abstract class ClickableUserContainer : Container { - private readonly SpriteText text; - protected override IEnumerable EffectTargets => new[] { text }; - private UserProfileOverlay profile; private User user; @@ -28,33 +26,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (user == value) return; user = value; - OnUserUpdate(user); + OnUserChange(user); } } - public float TextSize - { - set - { - if (text.TextSize == value) return; - text.TextSize = value; - } - get { return text.TextSize; } - } - - public ClickableUsername() + public ClickableUserContainer() { AutoSizeAxes = Axes.Both; - Child = text = new SpriteText - { - Font = @"Exo2.0-BoldItalic", - }; } - protected virtual void OnUserUpdate(User user) - { - text.Text = user.Username; - } + protected abstract void OnUserChange(User user); [BackgroundDependencyLoader(true)] private void load(UserProfileOverlay profile) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 609524f170..6f6fd22a13 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -16,62 +17,63 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Users; using osuTK; +using osuTK.Graphics; +using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { public class DrawableScore : Container { private const int fade_duration = 100; - private const float side_margin = 20; + private const float text_size = 14; private readonly Box background; + private readonly Box hoveredBackground; + private readonly SpriteText rank; + private readonly SpriteText scoreText; + private readonly SpriteText accuracy; + private readonly SpriteText maxCombo; + private readonly SpriteText hitGreat; + private readonly SpriteText hitGood; + private readonly SpriteText hitMeh; + private readonly SpriteText hitMiss; + private readonly SpriteText pp; + + private readonly ClickableScoreUsername username; + + private readonly APIScoreInfo score; + private Color4 backgroundColor; public DrawableScore(int index, APIScoreInfo score) { - ScoreModsContainer modsContainer; + FillFlowContainer modsContainer; + + this.score = score; RelativeSizeAxes = Axes.X; - Height = 30; + Height = 25; CornerRadius = 3; Masking = true; Children = new Drawable[] { background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + hoveredBackground = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0, }, - new OsuSpriteText + rank = new SpriteText { Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Origin = Anchor.CentreRight, Text = $"#{index + 1}", - Font = @"Exo2.0-RegularItalic", - Margin = new MarginPadding { Left = side_margin } - }, - new DrawableFlag(score.User.Country) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(30, 20), - Margin = new MarginPadding { Left = 60 } - }, - //new ClickableUsername - //{ - // Anchor = Anchor.CentreLeft, - // Origin = Anchor.CentreLeft, - // User = score.User, - // Margin = new MarginPadding { Left = 100 } - //}, - modsContainer = new ScoreModsContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Width = 0.06f, - RelativePositionAxes = Axes.X, - X = 0.42f + TextSize = text_size, + X = ScoreTextLine.RANK_POSITION, + Font = @"Exo2.0-Bold", + Colour = Color4.Black, }, new DrawableRank(score.Rank) { @@ -79,64 +81,232 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, Size = new Vector2(30, 20), FillMode = FillMode.Fit, - RelativePositionAxes = Axes.X, - X = 0.55f + X = 45 }, - new OsuSpriteText + scoreText = new SpriteText { Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, + Origin = Anchor.CentreLeft, Text = $@"{score.TotalScore:N0}", - Font = @"Venera", - RelativePositionAxes = Axes.X, - X = 0.75f, - FixedWidth = true, + X = ScoreTextLine.SCORE_POSITION, + Colour = Color4.Black, + TextSize = text_size, }, - new OsuSpriteText + accuracy = new SpriteText { Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, + Origin = Anchor.CentreLeft, Text = $@"{score.Accuracy:P2}", - Font = @"Exo2.0-RegularItalic", - RelativePositionAxes = Axes.X, - X = 0.85f + X = ScoreTextLine.ACCURACY_POSITION, + TextSize = text_size, }, - new OsuSpriteText + new DrawableFlag(score.User.Country) { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Text = $"{score.Statistics[HitResult.Great]}/{score.Statistics[HitResult.Good]}/{score.Statistics[HitResult.Meh]}", - Font = @"Exo2.0-RegularItalic", - Margin = new MarginPadding { Right = side_margin } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20, 13), + X = 230, + }, + username = new ClickableScoreUsername + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + User = score.User, + X = ScoreTextLine.PLAYER_POSITION, + Colour = Color4.Black, + }, + maxCombo = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $@"{score.MaxCombo:N0}x", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.MAX_COMBO_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + hitGreat = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"{score.Statistics[HitResult.Great]}", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.HIT_GREAT_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + hitGood = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"{score.Statistics[HitResult.Good]}", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.HIT_GOOD_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + hitMeh = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"{score.Statistics[HitResult.Meh]}", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.HIT_MEH_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + hitMiss = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $"{score.Statistics[HitResult.Miss]}", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.HIT_MISS_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + pp = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Text = $@"{score.PP:N0}", + RelativePositionAxes = Axes.X, + X = ScoreTextLine.PP_POSITION, + TextSize = text_size, + Colour = Color4.Black, + }, + modsContainer = new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = ScoreTextLine.MODS_POSITION, }, }; + if (index == 0) + scoreText.Font = @"Exo2.0-Bold"; + + accuracy.Colour = (score.Accuracy == 1) ? Color4.Green : Color4.Black; + + hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.Black; + hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.Black; + hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.Black; + hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.Black; + + background.Colour = backgroundColor = (index % 2 == 0) ? Color4.WhiteSmoke : Color4.White; + + foreach (Mod mod in score.Mods) modsContainer.Add(new ModIcon(mod) { AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.35f), + Scale = new Vector2(0.3f), }); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = colours.Gray4; + hoveredBackground.Colour = colours.Gray4; } protected override bool OnHover(HoverEvent e) { - background.FadeIn(fade_duration, Easing.OutQuint); + hoveredBackground.FadeIn(fade_duration, Easing.OutQuint); + rank.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + scoreText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + accuracy.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + username.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + maxCombo.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + pp.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Great] != 0) + hitGreat.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Good] != 0) + hitGood.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Meh] != 0) + hitMeh.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Miss] != 0) + hitMiss.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - background.FadeOut(fade_duration, Easing.OutQuint); + hoveredBackground.FadeOut(fade_duration, Easing.OutQuint); + rank.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + scoreText.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + username.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + accuracy.FadeColour((score.Accuracy == 1) ? Color4.Green : Color4.Black, fade_duration, Easing.OutQuint); + maxCombo.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + pp.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Great] != 0) + hitGreat.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Good] != 0) + hitGood.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Meh] != 0) + hitMeh.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + + if (score.Statistics[HitResult.Miss] != 0) + hitMiss.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + base.OnHoverLost(e); } protected override bool OnClick(ClickEvent e) => true; + + private class ClickableScoreUsername : ClickableUserContainer + { + private readonly SpriteText text; + private readonly SpriteText textBold; + + public ClickableScoreUsername() + { + Add(text = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + }); + + Add(textBold = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Font = @"Exo2.0-Bold", + Alpha = 0, + }); + } + + protected override void OnUserChange(User user) + { + text.Text = textBold.Text = user.Username; + } + + protected override bool OnHover(HoverEvent e) + { + textBold.FadeIn(fade_duration, Easing.OutQuint); + text.FadeOut(fade_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + textBold.FadeOut(fade_duration, Easing.OutQuint); + text.FadeIn(fade_duration, Easing.OutQuint); + base.OnHoverLost(e); + } + } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index d061e176e0..7d82b05099 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box background; private readonly UpdateableAvatar avatar; private readonly DrawableFlag flag; - private readonly ClickableUsername username; + private readonly ClickableTopScoreUsername username; private readonly SpriteText rankText; private readonly SpriteText date; private readonly DrawableRank rank; @@ -262,44 +262,70 @@ namespace osu.Game.Overlays.BeatmapSet.Scores base.OnHoverLost(e); } - private class ClickableTopScoreUsername : ClickableUsername + private class ClickableTopScoreUsername : ClickableUserContainer { - private Box underscore; + private const float fade_duration = 500; + + private readonly Box underscore; + private readonly Container underscoreContainer; + private readonly SpriteText text; + + private Color4 hoverColour; + + public float TextSize + { + set + { + if (text.TextSize == value) return; + text.TextSize = value; + } + get { return text.TextSize; } + } public ClickableTopScoreUsername() { - Add(new Container + Add(underscoreContainer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, Height = 1, - Position = new Vector2(0, TextSize / 2 - 1), - Depth = 1, Child = underscore = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0, } }); + Add(text = new SpriteText + { + Font = @"Exo2.0-BoldItalic", + Colour = Color4.Black, + }); } [BackgroundDependencyLoader] private void load(OsuColour colours) { - IdleColour = colours.ContextMenuGray; - HoverColour = underscore.Colour = colours.Blue; + hoverColour = underscore.Colour = colours.Blue; + underscoreContainer.Position = new Vector2(0, TextSize / 2 - 1); + } + + protected override void OnUserChange(User user) + { + text.Text = user.Username; } protected override bool OnHover(HoverEvent e) { - underscore.FadeIn(FADE_DURATION, Easing.OutQuint); + text.FadeColour(hoverColour, fade_duration, Easing.OutQuint); + underscore.FadeIn(fade_duration, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - underscore.FadeOut(FADE_DURATION, Easing.OutQuint); + text.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); + underscore.FadeOut(fade_duration, Easing.OutQuint); base.OnHoverLost(e); } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs new file mode 100644 index 0000000000..d8655b4882 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -0,0 +1,118 @@ +// 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.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTextLine : Container + { + private const float text_size = 12; + + public const float RANK_POSITION = 30; + public const float SCORE_POSITION = 90; + public const float ACCURACY_POSITION = 170; + public const float PLAYER_POSITION = 270; + public const float MAX_COMBO_POSITION = 0.5f; + public const float HIT_GREAT_POSITION = 0.6f; + public const float HIT_GOOD_POSITION = 0.65f; + public const float HIT_MEH_POSITION = 0.7f; + public const float HIT_MISS_POSITION = 0.75f; + public const float PP_POSITION = 0.8f; + public const float MODS_POSITION = 0.9f; + + public ScoreTextLine() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + new ScoreText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Text = "rank".ToUpper(), + X = RANK_POSITION, + }, + new ScoreText + { + Text = "score".ToUpper(), + X = SCORE_POSITION, + }, + new ScoreText + { + Text = "accuracy".ToUpper(), + X = ACCURACY_POSITION, + }, + new ScoreText + { + Text = "player".ToUpper(), + X = PLAYER_POSITION, + }, + new ScoreText + { + Text = "max combo".ToUpper(), + X = MAX_COMBO_POSITION, + RelativePositionAxes = Axes.X, + }, + new ScoreText + { + Text = "300", + RelativePositionAxes = Axes.X, + X = HIT_GREAT_POSITION, + }, + new ScoreText + { + Text = "100".ToUpper(), + RelativePositionAxes = Axes.X, + X = HIT_GOOD_POSITION, + }, + new ScoreText + { + Text = "50".ToUpper(), + RelativePositionAxes = Axes.X, + X = HIT_MEH_POSITION, + }, + new ScoreText + { + Text = "miss".ToUpper(), + RelativePositionAxes = Axes.X, + X = HIT_MISS_POSITION, + }, + new ScoreText + { + Text = "pp".ToUpper(), + RelativePositionAxes = Axes.X, + X = PP_POSITION, + }, + new ScoreText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Text = "mods".ToUpper(), + X = MODS_POSITION, + RelativePositionAxes = Axes.X, + }, + }; + } + + private class ScoreText : SpriteText + { + public ScoreText() + { + TextSize = text_size; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Colour = colours.ContextMenuGray; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index ac3068c2c8..5fd1084a14 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -1,19 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osuTK; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osuTK; +using osuTK.Graphics; using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; -using osu.Game.Beatmaps; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; -using osu.Framework.Graphics.Shapes; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -90,7 +90,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (scoreCount < 2) return; - for (int i = 1; i < scoreCount; i++) + flow.Add(new ScoreTextLine()); + + for (int i = 0; i < scoreCount; i++) flow.Add(new DrawableScore(i, scores.ElementAt(i))); } From 9cca11fb0d71c81f930cb48dd95a6ff9962cdd8f Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Wed, 6 Feb 2019 01:48:43 +0300 Subject: [PATCH 017/278] Warning fixes --- .../BeatmapSet/Scores/ClickableUserContainer.cs | 6 +----- osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs | 9 ++------- .../Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 12 +++++------- osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs | 1 - 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs index 2f402bfa74..621e1ee1f2 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs @@ -4,12 +4,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osu.Game.Users; -using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -30,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - public ClickableUserContainer() + protected ClickableUserContainer() { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 6f6fd22a13..c2f198d3ee 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -8,17 +8,14 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; -using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Users; using osuTK; using osuTK.Graphics; -using System.Collections.Generic; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -27,7 +24,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const int fade_duration = 100; private const float text_size = 14; - private readonly Box background; private readonly Box hoveredBackground; private readonly SpriteText rank; private readonly SpriteText scoreText; @@ -42,11 +38,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly ClickableScoreUsername username; private readonly APIScoreInfo score; - private Color4 backgroundColor; public DrawableScore(int index, APIScoreInfo score) { FillFlowContainer modsContainer; + Box background; this.score = score; @@ -196,8 +192,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.Black; hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.Black; - background.Colour = backgroundColor = (index % 2 == 0) ? Color4.WhiteSmoke : Color4.White; - + background.Colour = (index % 2 == 0) ? Color4.WhiteSmoke : Color4.White; foreach (Mod mod in score.Mods) modsContainer.Add(new ModIcon(mod) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 7d82b05099..48b824390d 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -10,10 +10,8 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; -using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -264,7 +262,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class ClickableTopScoreUsername : ClickableUserContainer { - private const float fade_duration = 500; + private const float username_fade_duration = 500; private readonly Box underscore; private readonly Container underscoreContainer; @@ -317,15 +315,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected override bool OnHover(HoverEvent e) { - text.FadeColour(hoverColour, fade_duration, Easing.OutQuint); - underscore.FadeIn(fade_duration, Easing.OutQuint); + text.FadeColour(hoverColour, username_fade_duration, Easing.OutQuint); + underscore.FadeIn(username_fade_duration, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - text.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - underscore.FadeOut(fade_duration, Easing.OutQuint); + text.FadeColour(Color4.Black, username_fade_duration, Easing.OutQuint); + underscore.FadeOut(username_fade_duration, Easing.OutQuint); base.OnHoverLost(e); } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index d8655b4882..53a477b908 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Framework.Localisation; using osu.Game.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores From f43ee6b6a36f12c54de0a2c941c27a01bcb85626 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 8 Feb 2019 19:06:46 +0300 Subject: [PATCH 018/278] update drawable top score inline with the latest design --- .../BeatmapSet/Scores/DrawableTopScore.cs | 85 ++++++++----------- .../BeatmapSet/Scores/ScoresContainer.cs | 7 -- 2 files changed, 35 insertions(+), 57 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 48b824390d..487194c819 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -30,6 +30,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const float avatar_size = 80; private const float margin = 10; + private OsuColour colours; + + private Color4 backgroundIdleColour => colours.Gray3; + private Color4 backgroundHoveredColour => colours.Gray4; + private readonly Box background; private readonly UpdateableAvatar avatar; private readonly DrawableFlag flag; @@ -38,8 +43,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly SpriteText date; private readonly DrawableRank rank; - private readonly AutoSizeInfoColumn totalScore; - private readonly MediumInfoColumn accuracy; + private readonly AutoSizedInfoColumn totalScore; + private readonly AutoSizedInfoColumn accuracy; private readonly MediumInfoColumn maxCombo; private readonly SmallInfoColumn hitGreat; @@ -56,7 +61,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores get { return score; } set { - if (score == value) return; + if (score == value) + return; score = value; avatar.User = username.User = score.User; @@ -83,7 +89,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - CornerRadius = 3; + CornerRadius = 10; Masking = true; EdgeEffect = new EdgeEffectParameters { @@ -97,7 +103,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores background = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.White, }, new Container { @@ -115,31 +120,20 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - new FillFlowContainer + rankText = new SpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), - Children = new Drawable[] - { - rankText = new SpriteText - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Text = "#1", - TextSize = 20, - Font = @"Exo2.0-BoldItalic", - }, - rank = new DrawableRank(ScoreRank.F) - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Size = new Vector2(30), - FillMode = FillMode.Fit, - }, - } + Text = "#1", + TextSize = 30, + Font = @"Exo2.0-BoldItalic", + }, + rank = new DrawableRank(ScoreRank.F) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(40), + FillMode = FillMode.Fit, }, avatar = new UpdateableAvatar { @@ -229,8 +223,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - totalScore = new AutoSizeInfoColumn("Total Score"), - accuracy = new MediumInfoColumn("Accuracy"), + totalScore = new AutoSizedInfoColumn("Total Score"), + accuracy = new AutoSizedInfoColumn("Accuracy"), maxCombo = new MediumInfoColumn("Max Combo"), } }, @@ -245,18 +239,21 @@ namespace osu.Game.Overlays.BeatmapSet.Scores [BackgroundDependencyLoader] private void load(OsuColour colours) { - date.Colour = rankText.Colour = colours.ContextMenuGray; + this.colours = colours; + + rankText.Colour = colours.Yellow; + background.Colour = backgroundIdleColour; } protected override bool OnHover(HoverEvent e) { - background.FadeColour(Color4.WhiteSmoke, fade_duration, Easing.OutQuint); + background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - background.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + background.FadeColour(backgroundIdleColour, fade_duration, Easing.OutQuint); base.OnHoverLost(e); } @@ -274,7 +271,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { set { - if (text.TextSize == value) return; + if (text.TextSize == value) + return; text.TextSize = value; } get { return text.TextSize; } @@ -297,7 +295,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Add(text = new SpriteText { Font = @"Exo2.0-BoldItalic", - Colour = Color4.Black, }); } @@ -322,7 +319,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected override void OnHoverLost(HoverLostEvent e) { - text.FadeColour(Color4.Black, username_fade_duration, Easing.OutQuint); + text.FadeColour(Color4.White, username_fade_duration, Easing.OutQuint); underscore.FadeOut(username_fade_duration, Easing.OutQuint); base.OnHoverLost(e); } @@ -348,6 +345,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { TextSize = 12, Text = header.ToUpper(), + Font = @"Exo2.0-Bold", } }, new Container @@ -362,12 +360,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - headerText.Colour = colours.ContextMenuGray; - } } private class ModsInfoColumn : DrawableInfoColumn @@ -420,20 +412,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Add(valueText = new SpriteText { TextSize = valueTextSize, - Font = @"Exo2.0-Light", }); } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - valueText.Colour = colours.ContextMenuGray; - } } - private class AutoSizeInfoColumn : TextInfoColumn + private class AutoSizedInfoColumn : TextInfoColumn { - public AutoSizeInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + public AutoSizedInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 5fd1084a14..5211f1398f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -4,14 +4,12 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osuTK; -using osuTK.Graphics; using System.Collections.Generic; using System.Linq; @@ -102,11 +100,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores AutoSizeAxes = Axes.Y; Children = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, new FillFlowContainer { Anchor = Anchor.TopCentre, From 7a3ae0f479bebb101ad8b00828419ff0eae5291d Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 8 Feb 2019 19:50:02 +0300 Subject: [PATCH 019/278] update drawable score inline with the latest design --- .../BeatmapSet/Scores/DrawableScore.cs | 75 ++++--------------- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 58 ++++++++++++++ .../BeatmapSet/Scores/ScoreTextLine.cs | 16 +--- .../BeatmapSet/Scores/ScoresContainer.cs | 22 +++--- 4 files changed, 87 insertions(+), 84 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index c2f198d3ee..1076fe6449 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -25,6 +25,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const float text_size = 14; private readonly Box hoveredBackground; + private readonly Box background; + private readonly SpriteText rank; private readonly SpriteText scoreText; private readonly SpriteText accuracy; @@ -39,10 +41,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly APIScoreInfo score; - public DrawableScore(int index, APIScoreInfo score) + public DrawableScore(int index, APIScoreInfo score, int maxModsAmount) { FillFlowContainer modsContainer; - Box background; this.score = score; @@ -69,7 +70,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores TextSize = text_size, X = ScoreTextLine.RANK_POSITION, Font = @"Exo2.0-Bold", - Colour = Color4.Black, }, new DrawableRank(score.Rank) { @@ -85,7 +85,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, Text = $@"{score.TotalScore:N0}", X = ScoreTextLine.SCORE_POSITION, - Colour = Color4.Black, TextSize = text_size, }, accuracy = new SpriteText @@ -109,7 +108,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, User = score.User, X = ScoreTextLine.PLAYER_POSITION, - Colour = Color4.Black, }, maxCombo = new SpriteText { @@ -119,7 +117,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.MAX_COMBO_POSITION, TextSize = text_size, - Colour = Color4.Black, }, hitGreat = new SpriteText { @@ -129,7 +126,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.HIT_GREAT_POSITION, TextSize = text_size, - Colour = Color4.Black, }, hitGood = new SpriteText { @@ -139,7 +135,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.HIT_GOOD_POSITION, TextSize = text_size, - Colour = Color4.Black, }, hitMeh = new SpriteText { @@ -149,7 +144,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.HIT_MEH_POSITION, TextSize = text_size, - Colour = Color4.Black, }, hitMiss = new SpriteText { @@ -159,7 +153,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.HIT_MISS_POSITION, TextSize = text_size, - Colour = Color4.Black, }, pp = new SpriteText { @@ -169,34 +162,35 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativePositionAxes = Axes.X, X = ScoreTextLine.PP_POSITION, TextSize = text_size, - Colour = Color4.Black, }, modsContainer = new FillFlowContainer { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = ScoreTextLine.MODS_POSITION, + X = -30 * maxModsAmount, }, }; if (index == 0) scoreText.Font = @"Exo2.0-Bold"; - accuracy.Colour = (score.Accuracy == 1) ? Color4.Green : Color4.Black; + accuracy.Colour = (score.Accuracy == 1) ? Color4.LightGreen : Color4.White; - hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.Black; - hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.Black; - hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.Black; - hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.Black; + hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.White; + hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.White; + hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.White; + hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.White; - background.Colour = (index % 2 == 0) ? Color4.WhiteSmoke : Color4.White; + if (index % 2 == 0) + background.Alpha = 0; foreach (Mod mod in score.Mods) modsContainer.Add(new ModIcon(mod) { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, Scale = new Vector2(0.3f), }); @@ -206,55 +200,18 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private void load(OsuColour colours) { hoveredBackground.Colour = colours.Gray4; + background.Colour = colours.Gray3; } protected override bool OnHover(HoverEvent e) { hoveredBackground.FadeIn(fade_duration, Easing.OutQuint); - rank.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - scoreText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - accuracy.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - username.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - maxCombo.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - pp.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Great] != 0) - hitGreat.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Good] != 0) - hitGood.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Meh] != 0) - hitMeh.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Miss] != 0) - hitMiss.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { hoveredBackground.FadeOut(fade_duration, Easing.OutQuint); - rank.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - scoreText.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - username.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - accuracy.FadeColour((score.Accuracy == 1) ? Color4.Green : Color4.Black, fade_duration, Easing.OutQuint); - maxCombo.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - pp.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Great] != 0) - hitGreat.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Good] != 0) - hitGood.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Meh] != 0) - hitMeh.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - - if (score.Statistics[HitResult.Miss] != 0) - hitMiss.FadeColour(Color4.Black, fade_duration, Easing.OutQuint); - base.OnHoverLost(e); } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs new file mode 100644 index 0000000000..90947364e4 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using System.Collections.Generic; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTable : FillFlowContainer + { + private IEnumerable scores; + public IEnumerable Scores + { + set + { + scores = value; + + int maxModsAmount = 0; + foreach (var s in scores) + { + var scoreModsAmount = s.Mods.Length; + if (scoreModsAmount > maxModsAmount) + maxModsAmount = scoreModsAmount; + } + + Add(new ScoreTextLine(maxModsAmount)); + + + int index = 0; + foreach (var s in scores) + Add(new DrawableScore(index++, s, maxModsAmount)); + } + get + { + return scores; + } + } + + public ScoreTable() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + } + + public void ClearScores() + { + scores = null; + foreach (var s in this) + { + if (s is DrawableScore) + Remove(s); + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index 53a477b908..43255683c4 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -23,9 +23,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public const float HIT_MEH_POSITION = 0.7f; public const float HIT_MISS_POSITION = 0.75f; public const float PP_POSITION = 0.8f; - public const float MODS_POSITION = 0.9f; - public ScoreTextLine() + public ScoreTextLine(int maxModsAmount) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -91,11 +90,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }, new ScoreText { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, Text = "mods".ToUpper(), - X = MODS_POSITION, - RelativePositionAxes = Axes.X, + X = -30 * maxModsAmount, }, }; } @@ -106,12 +104,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { TextSize = text_size; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Colour = colours.ContextMenuGray; - } } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 5211f1398f..8f3414c292 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -20,7 +20,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const int spacing = 15; private const int fade_duration = 200; - private readonly FillFlowContainer flow; + private readonly ScoreTable scoreTable; + private readonly DrawableTopScore topScore; private readonly LoadingAnimation loadingAnimation; @@ -76,22 +77,19 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (scoreCount == 0) { topScore.Hide(); - flow.Clear(); + scoreTable.ClearScores(); return; } topScore.Score = scores.FirstOrDefault(); topScore.Show(); - flow.Clear(); + scoreTable.ClearScores(); if (scoreCount < 2) return; - flow.Add(new ScoreTextLine()); - - for (int i = 0; i < scoreCount; i++) - flow.Add(new DrawableScore(i, scores.ElementAt(i))); + scoreTable.Scores = scores; } public ScoresContainer() @@ -113,13 +111,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Children = new Drawable[] { topScore = new DrawableTopScore(), - flow = new FillFlowContainer + scoreTable = new ScoreTable { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 1), - }, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + } } }, loadingAnimation = new LoadingAnimation From 13c154a0b37f2c4c89f66d697dab122ec9a754d4 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 8 Feb 2019 20:07:21 +0300 Subject: [PATCH 020/278] Fix background colour and a bug with removing scores --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 7 ++----- .../Overlays/BeatmapSet/Scores/ScoresContainer.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 90947364e4..7de13b7204 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -48,11 +49,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public void ClearScores() { scores = null; - foreach (var s in this) - { - if (s is DrawableScore) - Remove(s); - } + Clear(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 8f3414c292..2a9e76874e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -4,12 +4,15 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osuTK; +using osuTK.Graphics; using System.Collections.Generic; using System.Linq; @@ -20,6 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const int spacing = 15; private const int fade_duration = 200; + private readonly Box background; private readonly ScoreTable scoreTable; private readonly DrawableTopScore topScore; @@ -98,6 +102,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores AutoSizeAxes = Axes.Y; Children = new Drawable[] { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, new FillFlowContainer { Anchor = Anchor.TopCentre, @@ -127,9 +135,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(APIAccess api) + private void load(APIAccess api, OsuColour colours) { this.api = api; + + background.Colour = colours.Gray2; updateDisplay(); } From bd1f4f954955bf426225e67d9db270c275135483 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 8 Feb 2019 20:35:07 +0300 Subject: [PATCH 021/278] Small design fixes --- .../BeatmapSet/Scores/DrawableScore.cs | 2 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 1076fe6449..cb9d89dc2c 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -176,7 +176,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (index == 0) scoreText.Font = @"Exo2.0-Bold"; - accuracy.Colour = (score.Accuracy == 1) ? Color4.LightGreen : Color4.White; + accuracy.Colour = (score.Accuracy == 1) ? Color4.GreenYellow : Color4.White; hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.White; hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.White; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 487194c819..903e86423b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -169,7 +169,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 10, + TextSize = 15, + Font = @"Exo2.0-Bold", }, flag = new DrawableFlag { @@ -327,9 +328,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class DrawableInfoColumn : FillFlowContainer { - private readonly SpriteText headerText; private const float header_text_size = 12; + private readonly SpriteText headerText; + private readonly Box line; + public DrawableInfoColumn(string header) { AutoSizeAxes = Axes.Y; @@ -351,15 +354,20 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new Container { RelativeSizeAxes = Axes.X, - Height = 3, - Child = new Box + Height = 2, + Child = line = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.LightGray, } } }; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + line.Colour = colours.Gray5; + } } private class ModsInfoColumn : DrawableInfoColumn From 107e0a5239be8e629d4c0a5498fd49ff03e082be Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Fri, 8 Feb 2019 20:43:11 +0300 Subject: [PATCH 022/278] Warning fixes --- .../BeatmapSet/Scores/DrawableScore.cs | 31 +++++++------------ .../BeatmapSet/Scores/DrawableTopScore.cs | 7 ++--- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 -- .../BeatmapSet/Scores/ScoreTextLine.cs | 2 -- .../BeatmapSet/Scores/ScoresContainer.cs | 1 - 5 files changed, 14 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index cb9d89dc2c..d37bbe5db0 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -27,25 +27,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box hoveredBackground; private readonly Box background; - private readonly SpriteText rank; - private readonly SpriteText scoreText; - private readonly SpriteText accuracy; - private readonly SpriteText maxCombo; - private readonly SpriteText hitGreat; - private readonly SpriteText hitGood; - private readonly SpriteText hitMeh; - private readonly SpriteText hitMiss; - private readonly SpriteText pp; - - private readonly ClickableScoreUsername username; - - private readonly APIScoreInfo score; - public DrawableScore(int index, APIScoreInfo score, int maxModsAmount) { - FillFlowContainer modsContainer; + SpriteText accuracy; + SpriteText scoreText; + SpriteText hitGreat; + SpriteText hitGood; + SpriteText hitMeh; + SpriteText hitMiss; - this.score = score; + FillFlowContainer modsContainer; RelativeSizeAxes = Axes.X; Height = 25; @@ -62,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.Both, Alpha = 0, }, - rank = new SpriteText + new SpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreRight, @@ -102,14 +93,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Size = new Vector2(20, 13), X = 230, }, - username = new ClickableScoreUsername + new ClickableScoreUsername { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, User = score.User, X = ScoreTextLine.PLAYER_POSITION, }, - maxCombo = new SpriteText + new SpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -154,7 +145,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores X = ScoreTextLine.HIT_MISS_POSITION, TextSize = text_size, }, - pp = new SpriteText + new SpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 903e86423b..d2421ec606 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -330,10 +330,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float header_text_size = 12; - private readonly SpriteText headerText; private readonly Box line; - public DrawableInfoColumn(string header) + protected DrawableInfoColumn(string header) { AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; @@ -344,7 +343,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { AutoSizeAxes = Axes.X, Height = header_text_size, - Child = headerText = new SpriteText + Child = new SpriteText { TextSize = 12, Text = header.ToUpper(), @@ -415,7 +414,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores get { return valueText.Text; } } - public TextInfoColumn(string header, float valueTextSize = 25) : base(header) + protected TextInfoColumn(string header, float valueTextSize = 25) : base(header) { Add(valueText = new SpriteText { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7de13b7204..1b20b2c382 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; -using System.Linq; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -28,7 +27,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Add(new ScoreTextLine(maxModsAmount)); - int index = 0; foreach (var s in scores) Add(new DrawableScore(index++, s, maxModsAmount)); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index 43255683c4..04934185a1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -1,11 +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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 2a9e76874e..2783b0483b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -12,7 +12,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osuTK; -using osuTK.Graphics; using System.Collections.Generic; using System.Linq; From 105053e91b01bfb86a8af60b82fa25b2a7acb344 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 9 Feb 2019 00:56:41 +0300 Subject: [PATCH 023/278] TestCase fix --- osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs | 8 ++++++-- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 321a38d087..bcc1774729 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -17,10 +17,11 @@ using osu.Game.Beatmaps; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; +using NUnit.Framework; namespace osu.Game.Tests.Visual { - [System.ComponentModel.Description("in BeatmapOverlay")] + [Description("in BeatmapOverlay")] public class TestCaseBeatmapScoresContainer : OsuTestCase { private readonly IEnumerable scores; @@ -160,11 +161,12 @@ namespace osu.Game.Tests.Visual Accuracy = 0.6543, }, }; - foreach(var s in scores) + foreach (var s in scores) { s.Statistics.Add(HitResult.Great, RNG.Next(2000)); s.Statistics.Add(HitResult.Good, RNG.Next(2000)); s.Statistics.Add(HitResult.Meh, RNG.Next(2000)); + s.Statistics.Add(HitResult.Miss, RNG.Next(2000)); } anotherScores = new[] @@ -277,6 +279,7 @@ namespace osu.Game.Tests.Visual s.Statistics.Add(HitResult.Great, RNG.Next(2000)); s.Statistics.Add(HitResult.Good, RNG.Next(2000)); s.Statistics.Add(HitResult.Meh, RNG.Next(2000)); + s.Statistics.Add(HitResult.Miss, RNG.Next(2000)); } topScoreInfo = new APIScoreInfo @@ -304,6 +307,7 @@ namespace osu.Game.Tests.Visual topScoreInfo.Statistics.Add(HitResult.Great, RNG.Next(2000)); topScoreInfo.Statistics.Add(HitResult.Good, RNG.Next(2000)); topScoreInfo.Statistics.Add(HitResult.Meh, RNG.Next(2000)); + topScoreInfo.Statistics.Add(HitResult.Miss, RNG.Next(2000)); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 2783b0483b..180f4a949c 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -73,6 +73,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private void updateDisplay() { + scoreTable.ClearScores(); + loading = false; var scoreCount = scores?.Count() ?? 0; @@ -80,15 +82,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores if (scoreCount == 0) { topScore.Hide(); - scoreTable.ClearScores(); return; } topScore.Score = scores.FirstOrDefault(); topScore.Show(); - scoreTable.ClearScores(); - if (scoreCount < 2) return; From 04e57d7d3dcd2dc7423a6ef077437abafcfeb7e9 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sat, 9 Feb 2019 06:23:58 +0300 Subject: [PATCH 024/278] Refactor to make things more flexible --- .../BeatmapSet/Scores/DrawableScore.cs | 242 ++++++++---------- .../BeatmapSet/Scores/DrawableTopScore.cs | 2 +- .../BeatmapSet/Scores/ScoreTableLine.cs | 183 +++++++++++++ .../BeatmapSet/Scores/ScoreTextLine.cs | 146 ++++------- 4 files changed, 341 insertions(+), 232 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index d37bbe5db0..8741fd8dfe 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -22,24 +22,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class DrawableScore : Container { private const int fade_duration = 100; - private const float text_size = 14; + private const int text_size = 14; private readonly Box hoveredBackground; private readonly Box background; public DrawableScore(int index, APIScoreInfo score, int maxModsAmount) { - SpriteText accuracy; - SpriteText scoreText; - SpriteText hitGreat; - SpriteText hitGood; - SpriteText hitMeh; - SpriteText hitMiss; - - FillFlowContainer modsContainer; - RelativeSizeAxes = Axes.X; - Height = 25; + AutoSizeAxes = Axes.Y; CornerRadius = 3; Masking = true; Children = new Drawable[] @@ -53,138 +44,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.Both, Alpha = 0, }, - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Text = $"#{index + 1}", - TextSize = text_size, - X = ScoreTextLine.RANK_POSITION, - Font = @"Exo2.0-Bold", - }, - new DrawableRank(score.Rank) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(30, 20), - FillMode = FillMode.Fit, - X = 45 - }, - scoreText = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $@"{score.TotalScore:N0}", - X = ScoreTextLine.SCORE_POSITION, - TextSize = text_size, - }, - accuracy = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $@"{score.Accuracy:P2}", - X = ScoreTextLine.ACCURACY_POSITION, - TextSize = text_size, - }, - new DrawableFlag(score.User.Country) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(20, 13), - X = 230, - }, - new ClickableScoreUsername - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - User = score.User, - X = ScoreTextLine.PLAYER_POSITION, - }, - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $@"{score.MaxCombo:N0}x", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.MAX_COMBO_POSITION, - TextSize = text_size, - }, - hitGreat = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"{score.Statistics[HitResult.Great]}", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.HIT_GREAT_POSITION, - TextSize = text_size, - }, - hitGood = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"{score.Statistics[HitResult.Good]}", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.HIT_GOOD_POSITION, - TextSize = text_size, - }, - hitMeh = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"{score.Statistics[HitResult.Meh]}", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.HIT_MEH_POSITION, - TextSize = text_size, - }, - hitMiss = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $"{score.Statistics[HitResult.Miss]}", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.HIT_MISS_POSITION, - TextSize = text_size, - }, - new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Text = $@"{score.PP:N0}", - RelativePositionAxes = Axes.X, - X = ScoreTextLine.PP_POSITION, - TextSize = text_size, - }, - modsContainer = new FillFlowContainer - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - X = -30 * maxModsAmount, - }, + new DrawableScoreData(index, score, maxModsAmount), }; - if (index == 0) - scoreText.Font = @"Exo2.0-Bold"; - - accuracy.Colour = (score.Accuracy == 1) ? Color4.GreenYellow : Color4.White; - - hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.White; - hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.White; - hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.White; - hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.White; - - if (index % 2 == 0) + if (index % 2 != 0) background.Alpha = 0; - - foreach (Mod mod in score.Mods) - modsContainer.Add(new ModIcon(mod) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f), - }); } [BackgroundDependencyLoader] @@ -251,5 +115,103 @@ namespace osu.Game.Overlays.BeatmapSet.Scores base.OnHoverLost(e); } } + + private class DrawableScoreData : ScoreTableLine + { + public DrawableScoreData(int index, APIScoreInfo score, int maxModsAmount) : base(maxModsAmount) + { + SpriteText scoreText; + SpriteText accuracy; + SpriteText hitGreat; + SpriteText hitGood; + SpriteText hitMeh; + SpriteText hitMiss; + + FillFlowContainer modsContainer; + + RankContainer.Add(new SpriteText + { + Text = $"#{index + 1}", + Font = @"Exo2.0-Bold", + TextSize = text_size, + }); + DrawableRankContainer.Add(new DrawableRank(score.Rank) + { + Size = new Vector2(30, 20), + FillMode = FillMode.Fit, + }); + ScoreContainer.Add(scoreText = new SpriteText + { + Text = $@"{score.TotalScore:N0}", + TextSize = text_size, + }); + AccuracyContainer.Add(accuracy = new SpriteText + { + Text = $@"{score.Accuracy:P2}", + TextSize = text_size, + }); + FlagContainer.Add(new DrawableFlag(score.User.Country) + { + Size = new Vector2(20, 13), + }); + PlayerContainer.Add(new ClickableScoreUsername + { + User = score.User, + }); + MaxComboContainer.Add(new SpriteText + { + Text = $@"{score.MaxCombo:N0}x", + TextSize = text_size, + }); + HitGreatContainer.Add(hitGreat = new SpriteText + { + Text = $"{score.Statistics[HitResult.Great]}", + TextSize = text_size, + }); + HitGoodContainer.Add(hitGood = new SpriteText + { + Text = $"{score.Statistics[HitResult.Good]}", + TextSize = text_size, + }); + HitMehContainer.Add(hitMeh = new SpriteText + { + Text = $"{score.Statistics[HitResult.Meh]}", + TextSize = text_size, + }); + HitMissContainer.Add(hitMiss = new SpriteText + { + Text = $"{score.Statistics[HitResult.Miss]}", + TextSize = text_size, + }); + PPContainer.Add(new SpriteText + { + Text = $@"{score.PP:N0}", + TextSize = text_size, + }); + ModsContainer.Add(modsContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + }); + + if (index == 0) + scoreText.Font = @"Exo2.0-Bold"; + + accuracy.Colour = (score.Accuracy == 1) ? Color4.GreenYellow : Color4.White; + hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.White; + hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.White; + hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.White; + hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.White; + + foreach (Mod mod in score.Mods) + modsContainer.Add(new ModIcon(mod) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f), + }); + } + } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index d2421ec606..7623153710 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -188,7 +188,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Width = 0.7f, + Width = 0.65f, Child = new FillFlowContainer { AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs new file mode 100644 index 0000000000..d57225b541 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs @@ -0,0 +1,183 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTableLine : GridContainer + { + private const float rank_position = 30; + private const float drawable_rank_position = 45; + private const float score_position = 90; + private const float accuracy_position = 170; + private const float flag_position = 220; + private const float player_position = 250; + + private const float max_combo_position = 0.1f; + private const float hit_great_position = 0.3f; + private const float hit_good_position = 0.45f; + private const float hit_meh_position = 0.6f; + private const float hit_miss_position = 0.75f; + private const float pp_position = 0.9f; + + protected readonly Container RankContainer; + protected readonly Container DrawableRankContainer; + protected readonly Container ScoreContainer; + protected readonly Container AccuracyContainer; + protected readonly Container FlagContainer; + protected readonly Container PlayerContainer; + protected readonly Container MaxComboContainer; + protected readonly Container HitGreatContainer; + protected readonly Container HitGoodContainer; + protected readonly Container HitMehContainer; + protected readonly Container HitMissContainer; + protected readonly Container PPContainer; + protected readonly Container ModsContainer; + + public ScoreTableLine(int maxModsAmount) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + RowDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, 25), + }; + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, 300), + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + }; + Content = new[] + { + new Drawable[] + { + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + RankContainer = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + X = rank_position, + }, + DrawableRankContainer = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = drawable_rank_position, + }, + ScoreContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = score_position, + }, + AccuracyContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = accuracy_position, + }, + FlagContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = flag_position, + }, + PlayerContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = player_position, + } + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + MaxComboContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = max_combo_position, + }, + HitGreatContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = hit_great_position, + }, + HitGoodContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = hit_good_position, + }, + HitMehContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = hit_meh_position, + }, + HitMissContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = hit_miss_position, + }, + PPContainer = new Container + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = pp_position, + } + } + }, + new Container + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = ModsContainer = new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + X = -30 * maxModsAmount, + } + } + } + }; + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index 04934185a1..b7c9742764 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -1,107 +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 osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTextLine : Container + public class ScoreTextLine : ScoreTableLine { private const float text_size = 12; - public const float RANK_POSITION = 30; - public const float SCORE_POSITION = 90; - public const float ACCURACY_POSITION = 170; - public const float PLAYER_POSITION = 270; - public const float MAX_COMBO_POSITION = 0.5f; - public const float HIT_GREAT_POSITION = 0.6f; - public const float HIT_GOOD_POSITION = 0.65f; - public const float HIT_MEH_POSITION = 0.7f; - public const float HIT_MISS_POSITION = 0.75f; - public const float PP_POSITION = 0.8f; - - public ScoreTextLine(int maxModsAmount) + public ScoreTextLine(int maxModsAmount) : base(maxModsAmount) { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] + RankContainer.Add(new SpriteText { - new ScoreText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - Text = "rank".ToUpper(), - X = RANK_POSITION, - }, - new ScoreText - { - Text = "score".ToUpper(), - X = SCORE_POSITION, - }, - new ScoreText - { - Text = "accuracy".ToUpper(), - X = ACCURACY_POSITION, - }, - new ScoreText - { - Text = "player".ToUpper(), - X = PLAYER_POSITION, - }, - new ScoreText - { - Text = "max combo".ToUpper(), - X = MAX_COMBO_POSITION, - RelativePositionAxes = Axes.X, - }, - new ScoreText - { - Text = "300", - RelativePositionAxes = Axes.X, - X = HIT_GREAT_POSITION, - }, - new ScoreText - { - Text = "100".ToUpper(), - RelativePositionAxes = Axes.X, - X = HIT_GOOD_POSITION, - }, - new ScoreText - { - Text = "50".ToUpper(), - RelativePositionAxes = Axes.X, - X = HIT_MEH_POSITION, - }, - new ScoreText - { - Text = "miss".ToUpper(), - RelativePositionAxes = Axes.X, - X = HIT_MISS_POSITION, - }, - new ScoreText - { - Text = "pp".ToUpper(), - RelativePositionAxes = Axes.X, - X = PP_POSITION, - }, - new ScoreText - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - Text = "mods".ToUpper(), - X = -30 * maxModsAmount, - }, - }; - } - - private class ScoreText : SpriteText - { - public ScoreText() + Text = @"rank".ToUpper(), + TextSize = text_size, + }); + ScoreContainer.Add(new SpriteText { - TextSize = text_size; - } + Text = @"score".ToUpper(), + TextSize = text_size, + }); + AccuracyContainer.Add(new SpriteText + { + Text = @"accuracy".ToUpper(), + TextSize = text_size, + }); + PlayerContainer.Add(new SpriteText + { + Text = @"player".ToUpper(), + TextSize = text_size, + }); + MaxComboContainer.Add(new SpriteText + { + Text = @"max combo".ToUpper(), + TextSize = text_size, + }); + HitGreatContainer.Add(new SpriteText + { + Text = "300".ToUpper(), + TextSize = text_size, + }); + HitGoodContainer.Add(new SpriteText + { + Text = "100".ToUpper(), + TextSize = text_size, + }); + HitMehContainer.Add(new SpriteText + { + Text = "50".ToUpper(), + TextSize = text_size, + }); + HitMissContainer.Add(new SpriteText + { + Text = @"miss".ToUpper(), + TextSize = text_size, + }); + PPContainer.Add(new SpriteText + { + Text = @"pp".ToUpper(), + TextSize = text_size, + }); + ModsContainer.Add(new SpriteText + { + Text = @"mods".ToUpper(), + TextSize = text_size, + }); } } } From 4d489da03280c51ca1ff2b88f9d00d4dcdf2e715 Mon Sep 17 00:00:00 2001 From: EVAST9919 Date: Sun, 10 Feb 2019 04:16:56 +0300 Subject: [PATCH 025/278] small visual improvements --- .../BeatmapSet/Scores/DrawableTopScore.cs | 12 ++--- .../BeatmapSet/Scores/ScoreTableLine.cs | 2 +- .../BeatmapSet/Scores/ScoreTextLine.cs | 48 +++++++++---------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 7623153710..e4486b1514 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -200,8 +200,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { new FillFlowContainer { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(margin, 0), @@ -210,15 +210,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores hitGreat = new SmallInfoColumn("300", 20), hitGood = new SmallInfoColumn("100", 20), hitMeh = new SmallInfoColumn("50", 20), - hitMiss = new SmallInfoColumn("miss", 20), + hitMiss = new SmallInfoColumn("misses", 20), pp = new SmallInfoColumn("pp", 20), modsInfo = new ModsInfoColumn("mods"), } }, new FillFlowContainer { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(margin, 0), @@ -347,7 +347,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { TextSize = 12, Text = header.ToUpper(), - Font = @"Exo2.0-Bold", + Font = @"Exo2.0-Black", } }, new Container diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs index d57225b541..5c4723eae1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs @@ -173,7 +173,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - X = -30 * maxModsAmount, + X = -30 * ((maxModsAmount == 0) ? 1 : maxModsAmount), } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index b7c9742764..9fd12df3a8 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -7,65 +7,63 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { public class ScoreTextLine : ScoreTableLine { - private const float text_size = 12; - public ScoreTextLine(int maxModsAmount) : base(maxModsAmount) { - RankContainer.Add(new SpriteText + RankContainer.Add(new ScoreText { Text = @"rank".ToUpper(), - TextSize = text_size, }); - ScoreContainer.Add(new SpriteText + ScoreContainer.Add(new ScoreText { Text = @"score".ToUpper(), - TextSize = text_size, }); - AccuracyContainer.Add(new SpriteText + AccuracyContainer.Add(new ScoreText { Text = @"accuracy".ToUpper(), - TextSize = text_size, }); - PlayerContainer.Add(new SpriteText + PlayerContainer.Add(new ScoreText { Text = @"player".ToUpper(), - TextSize = text_size, }); - MaxComboContainer.Add(new SpriteText + MaxComboContainer.Add(new ScoreText { Text = @"max combo".ToUpper(), - TextSize = text_size, }); - HitGreatContainer.Add(new SpriteText + HitGreatContainer.Add(new ScoreText { Text = "300".ToUpper(), - TextSize = text_size, }); - HitGoodContainer.Add(new SpriteText + HitGoodContainer.Add(new ScoreText { Text = "100".ToUpper(), - TextSize = text_size, }); - HitMehContainer.Add(new SpriteText + HitMehContainer.Add(new ScoreText { Text = "50".ToUpper(), - TextSize = text_size, }); - HitMissContainer.Add(new SpriteText + HitMissContainer.Add(new ScoreText { - Text = @"miss".ToUpper(), - TextSize = text_size, + Text = @"misses".ToUpper(), }); - PPContainer.Add(new SpriteText + PPContainer.Add(new ScoreText { Text = @"pp".ToUpper(), - TextSize = text_size, }); - ModsContainer.Add(new SpriteText + ModsContainer.Add(new ScoreText { Text = @"mods".ToUpper(), - TextSize = text_size, }); } + + private class ScoreText : SpriteText + { + private const float text_size = 12; + + public ScoreText() + { + TextSize = text_size; + Font = @"Exo2.0-Black"; + } + } } } From 3c999d64d451db3ab3163cc6100790f967a9a11c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Mar 2019 16:09:21 +0900 Subject: [PATCH 026/278] Fix post-merge errors --- .../Profile/Header/CenterHeaderContainer.cs | 20 +++++++++---------- .../Profile/Header/ProfileHeaderTabControl.cs | 16 +++++++-------- osu.Game/Overlays/Profile/ProfileHeader.cs | 10 ++++------ 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index 30671487d3..fc330a03a9 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Configuration; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -108,8 +108,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 16, - Font = "Exo2.0-Bold" + Font = OsuFont.GetFont(weight: FontWeight.Bold) } } } @@ -182,10 +181,9 @@ namespace osu.Game.Overlays.Profile.Header }, levelBadgeText = new OsuSpriteText { - TextSize = 20, - Font = "Exo2.0-Medium", Anchor = Anchor.Centre, Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium) } } }, @@ -215,8 +213,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.BottomRight, Origin = Anchor.TopRight, - Font = "Exo2.0-Bold", - TextSize = 12, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold) } } }, @@ -248,9 +245,12 @@ namespace osu.Game.Overlays.Profile.Header } }; - DetailsVisible.ValueChanged += newValue => expandButtonIcon.Icon = newValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; - DetailsVisible.ValueChanged += newValue => hiddenDetailContainer.Alpha = newValue ? 1 : 0; - DetailsVisible.ValueChanged += newValue => expandedDetailContainer.Alpha = newValue ? 0 : 1; + DetailsVisible.ValueChanged += visible => + { + expandButtonIcon.Icon = visible.NewValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; + hiddenDetailContainer.Alpha = visible.NewValue ? 1 : 0; + expandedDetailContainer.Alpha = visible.NewValue ? 0 : 1; + }; } private void updateDisplay() diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index fd7124f20f..a8e50e00fe 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osuTK; @@ -36,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Header } } - public MarginPadding Padding + public new MarginPadding Padding { get => TabContainer.Padding; set => TabContainer.Padding = value; @@ -78,7 +79,7 @@ namespace osu.Game.Overlays.Profile.Header accentColour = value; bar.Colour = value; - if (!Active) text.Colour = value; + if (!Active.Value) text.Colour = value; } } @@ -96,8 +97,7 @@ namespace osu.Game.Overlays.Profile.Header Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Text = value, - TextSize = 14, - Font = "Exo2.0-Bold", + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) }, bar = new Circle { @@ -112,7 +112,7 @@ namespace osu.Game.Overlays.Profile.Header protected override bool OnHover(HoverEvent e) { - if (!Active) + if (!Active.Value) onActivated(true); return base.OnHover(e); } @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.Profile.Header { base.OnHoverLost(e); - if (!Active) + if (!Active.Value) OnDeactivated(); } @@ -134,7 +134,7 @@ namespace osu.Game.Overlays.Profile.Header { text.FadeColour(AccentColour, 120, Easing.InQuad); bar.ResizeHeightTo(0, 120, Easing.InQuad); - text.Font = "Exo2.0-Medium"; + text.Font = text.Font.With(Typeface.Exo, weight: FontWeight.Medium); } private void onActivated(bool fake = false) @@ -142,7 +142,7 @@ namespace osu.Game.Overlays.Profile.Header text.FadeColour(Color4.White, 120, Easing.InQuad); bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); if (!fake) - text.Font = "Exo2.0-Bold"; + text.Font = text.Font.With(Typeface.Exo, weight: FontWeight.Bold); } } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 21f1989606..fdb515270b 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Configuration; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,6 +14,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; +using osu.Framework.Bindables; namespace osu.Game.Overlays.Profile { @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Modding"); centerHeaderContainer.DetailsVisible.BindTo(DetailsVisible); - DetailsVisible.ValueChanged += newValue => detailHeaderContainer.Alpha = newValue ? 0 : 1; + DetailsVisible.ValueChanged += visible => detailHeaderContainer.Alpha = visible.NewValue ? 0 : 1; } [BackgroundDependencyLoader] @@ -224,13 +224,11 @@ namespace osu.Game.Overlays.Profile }, title = new OsuSpriteText { - Font = "Exo2.0-Bold", - TextSize = big ? 14 : 12, + Font = OsuFont.GetFont(size: big ? 14 : 12, weight: FontWeight.Bold) }, content = new OsuSpriteText { - Font = "Exo2.0-Light", - TextSize = big ? 40 : 18, + Font = OsuFont.GetFont(size: big ? 40 : 18, weight: FontWeight.Light) }, new Container //Add a minimum size to the FillFlowContainer { From e3d463a141269e4909b49ed6bf4c277de84dab44 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Mar 2019 16:30:56 +0900 Subject: [PATCH 027/278] Formatting fixes --- .../Graphics/Containers/OsuHoverContainer.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 9 ++++--- .../Profile/Header/CenterHeaderContainer.cs | 8 ++++-- .../Profile/Header/DetailHeaderContainer.cs | 8 ++++-- .../Profile/Header/MedalHeaderContainer.cs | 6 ++++- .../Profile/Header/TopHeaderContainer.cs | 6 ++++- osu.Game/Users/User.cs | 3 +++ osu.Game/Users/UserStatistics.cs | 25 +++++++++++++------ 8 files changed, 49 insertions(+), 18 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index f94fb2540c..1e0b56dae3 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Graphics.Containers [BackgroundDependencyLoader] private void load(OsuColour colours) { - if(HoverColour == default) + if (HoverColour == default) HoverColour = colours.Yellow; } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index df0409272f..7bb1b8acc2 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -24,13 +24,17 @@ namespace osu.Game.Overlays.Profile.Header private Color4 linkBlue, communityUserGrayGreenLighter; private User user; + public User User { get => user; set { - if (user == value) return; + if (user == value) + return; + user = value; + updateDisplay(); } } @@ -131,9 +135,8 @@ namespace osu.Game.Overlays.Profile.Header }); } else - { bottomLinkContainer.AddText(" " + content, bold); - } + addSpacer(bottomLinkContainer); } diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index fc330a03a9..ca615ccf4b 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -48,13 +48,17 @@ namespace osu.Game.Overlays.Profile.Header private APIAccess apiAccess { get; set; } private User user; + public User User { get => user; set { - if (user == value) return; + if (user == value) + return; + user = value; + updateDisplay(); } } @@ -183,7 +187,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium) + Font = OsuFont.GetFont(size: 20) } } }, diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 124299b0ba..a7d21bcdf3 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,13 +26,17 @@ namespace osu.Game.Overlays.Profile.Header private RankGraph rankGraph; private User user; + public User User { get => user; set { - if (user == value) return; + if (user == value) + return; + user = value; + updateDisplay(); } } @@ -181,7 +185,7 @@ namespace osu.Game.Overlays.Profile.Header totalPlayTimeTooltip.TooltipText = (user?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; foreach (var scoreRankInfo in scoreRankInfos) - scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount.GetForScoreRank(scoreRankInfo.Key) ?? 0; + scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; detailGlobalRank.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; detailCountryRank.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 5a54270b80..45c1e1e208 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -22,13 +22,17 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer badgeFlowContainer; private User user; + public User User { get => user; set { - if (user == value) return; + if (user == value) + return; + user = value; + updateDisplay(); } } diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 4186d08729..13a7951170 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -28,13 +28,17 @@ namespace osu.Game.Overlays.Profile.Header private const float avatar_size = 110; private User user; + public User User { get => user; set { - if (user == value) return; + if (user == value) + return; + user = value; + updateDisplay(); } } diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index d8e1ec81b5..314684069a 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -186,10 +186,13 @@ namespace osu.Game.Users { [Description("Keyboard")] Keyboard, + [Description("Mouse")] Mouse, + [Description("Tablet")] Tablet, + [Description("Touch Screen")] Touch, } diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index a69cd794b3..752534a80d 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -77,16 +77,25 @@ namespace osu.Game.Users [JsonProperty(@"a")] public int A; - public int GetForScoreRank(ScoreRank rank) + public int this[ScoreRank rank] { - switch (rank) + get { - case ScoreRank.XH: return SSPlus; - case ScoreRank.X: return SS; - case ScoreRank.SH: return SPlus; - case ScoreRank.S: return S; - case ScoreRank.A: return A; - default: throw new ArgumentException($"API does not return {rank.ToString()}"); + switch (rank) + { + case ScoreRank.XH: + return SSPlus; + case ScoreRank.X: + return SS; + case ScoreRank.SH: + return SPlus; + case ScoreRank.S: + return S; + case ScoreRank.A: + return A; + default: + throw new ArgumentException($"API does not return {rank.ToString()}"); + } } } } From 22423f60d42efe96c985289daa01fbc6900bd566 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Mar 2019 19:27:42 +0900 Subject: [PATCH 028/278] Fix DI not working --- osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs index 6f164890f9..49ffa2d63f 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual typeof(ProfileHeader), typeof(RankGraph), typeof(LineGraph), - typeof(SupporterIcon) + typeof(ProfileHeaderTabControl), }; [Resolved] From 8c0e325d8bc54ae802668c483ffdf30a6acbdd0f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 8 Mar 2019 16:40:37 +0900 Subject: [PATCH 029/278] Reduce + make beatmap scores testcase work --- .../Visual/TestCaseBeatmapScoresContainer.cs | 147 +----------------- 1 file changed, 6 insertions(+), 141 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 4ad5b2dc35..072bbff4cf 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -13,9 +13,7 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Rulesets.Osu; using osu.Game.Scoring; using NUnit.Framework; @@ -67,6 +65,7 @@ namespace osu.Game.Tests.Visual new OsuModHardRock(), }, Rank = ScoreRank.XH, + MaxCombo = 1234, TotalScore = 1234567890, Accuracy = 1, }, @@ -89,6 +88,7 @@ namespace osu.Game.Tests.Visual new OsuModFlashlight(), }, Rank = ScoreRank.S, + MaxCombo = 1234, TotalScore = 1234789, Accuracy = 0.9997, }, @@ -110,6 +110,7 @@ namespace osu.Game.Tests.Visual new OsuModHidden(), }, Rank = ScoreRank.B, + MaxCombo = 1234, TotalScore = 12345678, Accuracy = 0.9854, }, @@ -130,6 +131,7 @@ namespace osu.Game.Tests.Visual new OsuModDoubleTime(), }, Rank = ScoreRank.C, + MaxCombo = 1234, TotalScore = 1234567, Accuracy = 0.8765, }, @@ -146,6 +148,7 @@ namespace osu.Game.Tests.Visual }, }, Rank = ScoreRank.F, + MaxCombo = 1234, TotalScore = 123456, Accuracy = 0.6543, }, @@ -159,145 +162,7 @@ namespace osu.Game.Tests.Visual s.Statistics.Add(HitResult.Miss, RNG.Next(2000)); } - IEnumerable anotherScores = new[] - { - new APIScoreInfo - { - User = new User - { - Id = 4608074, - Username = @"Skycries", - Country = new Country - { - FullName = @"Brazil", - FlagName = @"BR", - }, - }, - Mods = new Mod[] - { - new OsuModDoubleTime(), - new OsuModHidden(), - new OsuModFlashlight(), - }, - Rank = ScoreRank.S, - TotalScore = 1234789, - Accuracy = 0.9997, - }, - new APIScoreInfo - { - User = new User - { - Id = 6602580, - Username = @"waaiiru", - Country = new Country - { - FullName = @"Spain", - FlagName = @"ES", - }, - }, - Mods = new Mod[] - { - new OsuModDoubleTime(), - new OsuModHidden(), - new OsuModFlashlight(), - new OsuModHardRock(), - }, - Rank = ScoreRank.XH, - TotalScore = 1234567890, - Accuracy = 1, - }, - new APIScoreInfo - { - User = new User - { - Id = 7151382, - Username = @"Mayuri Hana", - Country = new Country - { - FullName = @"Thailand", - FlagName = @"TH", - }, - }, - Rank = ScoreRank.F, - TotalScore = 123456, - Accuracy = 0.6543, - }, - new APIScoreInfo - { - User = new User - { - Id = 1014222, - Username = @"eLy", - Country = new Country - { - FullName = @"Japan", - FlagName = @"JP", - }, - }, - Mods = new Mod[] - { - new OsuModDoubleTime(), - new OsuModHidden(), - }, - Rank = ScoreRank.B, - TotalScore = 12345678, - Accuracy = 0.9854, - }, - new APIScoreInfo - { - User = new User - { - Id = 1541390, - Username = @"Toukai", - Country = new Country - { - FullName = @"Canada", - FlagName = @"CA", - }, - }, - Mods = new Mod[] - { - new OsuModDoubleTime(), - }, - Rank = ScoreRank.C, - TotalScore = 1234567, - Accuracy = 0.8765, - }, - }; - foreach (var s in anotherScores) - { - s.Statistics.Add(HitResult.Great, RNG.Next(2000)); - s.Statistics.Add(HitResult.Good, RNG.Next(2000)); - s.Statistics.Add(HitResult.Meh, RNG.Next(2000)); - s.Statistics.Add(HitResult.Miss, RNG.Next(2000)); - } - - var topScoreInfo = new APIScoreInfo - { - User = new User - { - Id = 2705430, - Username = @"Mooha", - Country = new Country - { - FullName = @"France", - FlagName = @"FR", - }, - }, - Mods = new Mod[] - { - new OsuModDoubleTime(), - new OsuModFlashlight(), - new OsuModHardRock(), - }, - Rank = ScoreRank.B, - TotalScore = 987654321, - Accuracy = 0.8487, - }; - topScoreInfo.Statistics.Add(HitResult.Great, RNG.Next(2000)); - topScoreInfo.Statistics.Add(HitResult.Good, RNG.Next(2000)); - topScoreInfo.Statistics.Add(HitResult.Meh, RNG.Next(2000)); - topScoreInfo.Statistics.Add(HitResult.Miss, RNG.Next(2000)); + scoresContainer.Scores = scores; } [BackgroundDependencyLoader] From a40ffcc6920d5bc25f0782727a1b967e1b1fc951 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 8 Mar 2019 16:44:39 +0900 Subject: [PATCH 030/278] Apply formatting adjustments --- .../Visual/TestCaseBeatmapScoresContainer.cs | 8 ++++-- .../Scores/ClickableUserContainer.cs | 1 - .../BeatmapSet/Scores/DrawableScore.cs | 3 ++- .../BeatmapSet/Scores/DrawableTopScore.cs | 25 +++++++++++++------ .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 6 ++--- .../BeatmapSet/Scores/ScoreTextLine.cs | 3 ++- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 072bbff4cf..ead743a283 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -26,10 +26,9 @@ namespace osu.Game.Tests.Visual public TestCaseBeatmapScoresContainer() { - Container container; ScoresContainer scoresContainer; - Child = container = new Container + Child = new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -65,6 +64,7 @@ namespace osu.Game.Tests.Visual new OsuModHardRock(), }, Rank = ScoreRank.XH, + PP = 200, MaxCombo = 1234, TotalScore = 1234567890, Accuracy = 1, @@ -88,6 +88,7 @@ namespace osu.Game.Tests.Visual new OsuModFlashlight(), }, Rank = ScoreRank.S, + PP = 190, MaxCombo = 1234, TotalScore = 1234789, Accuracy = 0.9997, @@ -110,6 +111,7 @@ namespace osu.Game.Tests.Visual new OsuModHidden(), }, Rank = ScoreRank.B, + PP = 180, MaxCombo = 1234, TotalScore = 12345678, Accuracy = 0.9854, @@ -131,6 +133,7 @@ namespace osu.Game.Tests.Visual new OsuModDoubleTime(), }, Rank = ScoreRank.C, + PP = 170, MaxCombo = 1234, TotalScore = 1234567, Accuracy = 0.8765, @@ -148,6 +151,7 @@ namespace osu.Game.Tests.Visual }, }, Rank = ScoreRank.F, + PP = 160, MaxCombo = 1234, TotalScore = 123456, Accuracy = 0.6543, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs index 3f1c8f56f5..cf1c3d7fcf 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Users; namespace osu.Game.Overlays.BeatmapSet.Scores diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 8741fd8dfe..19e999547b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -118,7 +118,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class DrawableScoreData : ScoreTableLine { - public DrawableScoreData(int index, APIScoreInfo score, int maxModsAmount) : base(maxModsAmount) + public DrawableScoreData(int index, APIScoreInfo score, int maxModsAmount) + : base(maxModsAmount) { SpriteText scoreText; SpriteText accuracy; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index e4486b1514..3712f38d02 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -56,13 +56,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly ModsInfoColumn modsInfo; private APIScoreInfo score; + public APIScoreInfo Score { - get { return score; } + get => score; set { if (score == value) return; + score = value; avatar.User = username.User = score.User; @@ -274,9 +276,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { if (text.TextSize == value) return; + text.TextSize = value; } - get { return text.TextSize; } + get => text.TextSize; } public ClickableTopScoreUsername() @@ -386,7 +389,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - public ModsInfoColumn(string header) : base(header) + public ModsInfoColumn(string header) + : base(header) { AutoSizeAxes = Axes.Both; Add(modsContainer = new FillFlowContainer @@ -409,12 +413,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { if (valueText.Text == value) return; + valueText.Text = value; } - get { return valueText.Text; } + get => valueText.Text; } - protected TextInfoColumn(string header, float valueTextSize = 25) : base(header) + protected TextInfoColumn(string header, float valueTextSize = 25) + : base(header) { Add(valueText = new SpriteText { @@ -425,7 +431,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class AutoSizedInfoColumn : TextInfoColumn { - public AutoSizedInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + public AutoSizedInfoColumn(string header, float valueTextSize = 25) + : base(header, valueTextSize) { AutoSizeAxes = Axes.Both; } @@ -435,7 +442,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float width = 70; - public MediumInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + public MediumInfoColumn(string header, float valueTextSize = 25) + : base(header, valueTextSize) { Width = width; } @@ -445,7 +453,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float width = 40; - public SmallInfoColumn(string header, float valueTextSize = 25) : base(header, valueTextSize) + public SmallInfoColumn(string header, float valueTextSize = 25) + : base(header, valueTextSize) { Width = width; } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 1b20b2c382..d69bc39bc6 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -11,6 +11,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class ScoreTable : FillFlowContainer { private IEnumerable scores; + public IEnumerable Scores { set @@ -31,10 +32,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores foreach (var s in scores) Add(new DrawableScore(index++, s, maxModsAmount)); } - get - { - return scores; - } + get => scores; } public ScoreTable() diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs index 9fd12df3a8..9e201bd98d 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs @@ -7,7 +7,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { public class ScoreTextLine : ScoreTableLine { - public ScoreTextLine(int maxModsAmount) : base(maxModsAmount) + public ScoreTextLine(int maxModsAmount) + : base(maxModsAmount) { RankContainer.Add(new ScoreText { From 9a05643ec980732837124698e535396c34ab73bf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 8 Mar 2019 17:18:54 +0900 Subject: [PATCH 031/278] Minor refactorings --- .../BeatmapSet/Scores/DrawableScore.cs | 2 + .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 45 +++--- .../BeatmapSet/Scores/ScoresContainer.cs | 140 +++++++++--------- 3 files changed, 97 insertions(+), 90 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 19e999547b..a2a9f9a01b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -31,8 +31,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + CornerRadius = 3; Masking = true; + Children = new Drawable[] { background = new Box diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index d69bc39bc6..4723fcaf2b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -5,47 +5,50 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTable : FillFlowContainer + public class ScoreTable : CompositeDrawable { - private IEnumerable scores; + private readonly FillFlowContainer scoresFlow; + + public ScoreTable() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChild = scoresFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }; + } public IEnumerable Scores { set { - scores = value; + scoresFlow.Clear(); + + if (value == null || !value.Any()) + return; int maxModsAmount = 0; - foreach (var s in scores) + foreach (var s in value) { var scoreModsAmount = s.Mods.Length; if (scoreModsAmount > maxModsAmount) maxModsAmount = scoreModsAmount; } - Add(new ScoreTextLine(maxModsAmount)); + scoresFlow.Add(new ScoreTextLine(maxModsAmount)); int index = 0; - foreach (var s in scores) - Add(new DrawableScore(index++, s, maxModsAmount)); + foreach (var s in value) + scoresFlow.Add(new DrawableScore(index++, s, maxModsAmount)); } - get => scores; - } - - public ScoreTable() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; - } - - public void ClearScores() - { - scores = null; - Clear(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index d99f391d21..6c90e192ac 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -17,7 +17,7 @@ using System.Linq; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoresContainer : Container + public class ScoresContainer : CompositeDrawable { private const int spacing = 15; private const int fade_duration = 200; @@ -28,77 +28,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly DrawableTopScore topScore; private readonly LoadingAnimation loadingAnimation; - private bool loading - { - set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration); - } - - private IEnumerable scores; - private BeatmapInfo beatmap; - - public IEnumerable Scores - { - get => scores; - set - { - getScoresRequest?.Cancel(); - scores = value; - - updateDisplay(); - } - } - - private GetScoresRequest getScoresRequest; - private APIAccess api; - - public BeatmapInfo Beatmap - { - get => beatmap; - set - { - beatmap = value; - - Scores = null; - - if (beatmap?.OnlineBeatmapID.HasValue != true) - return; - - loading = true; - - getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset); - getScoresRequest.Success += r => Schedule(() => Scores = r.Scores); - api.Queue(getScoresRequest); - } - } - - private void updateDisplay() - { - scoreTable.ClearScores(); - - loading = false; - - var scoreCount = scores?.Count() ?? 0; - - if (scoreCount == 0) - { - topScore.Hide(); - return; - } - - topScore.Score = scores.FirstOrDefault(); - topScore.Show(); - - if (scoreCount < 2) - return; - - scoreTable.Scores = scores; - } + [Resolved] + private APIAccess api { get; set; } public ScoresContainer() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Children = new Drawable[] + + InternalChildren = new Drawable[] { background = new Box { @@ -135,12 +73,76 @@ namespace osu.Game.Overlays.BeatmapSet.Scores [BackgroundDependencyLoader] private void load(APIAccess api, OsuColour colours) { - this.api = api; - background.Colour = colours.Gray2; updateDisplay(); } + private bool loading + { + set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration); + } + + private GetScoresRequest getScoresRequest; + + private IEnumerable scores; + + public IEnumerable Scores + { + get => scores; + set + { + getScoresRequest?.Cancel(); + scores = value; + + updateDisplay(); + } + } + + private BeatmapInfo beatmap; + + public BeatmapInfo Beatmap + { + get => beatmap; + set + { + beatmap = value; + + Scores = null; + + if (beatmap?.OnlineBeatmapID.HasValue != true) + return; + + loading = true; + + getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset); + getScoresRequest.Success += r => Schedule(() => Scores = r.Scores); + api.Queue(getScoresRequest); + } + } + + private void updateDisplay() + { + scoreTable.Scores = Enumerable.Empty(); + + loading = false; + + var scoreCount = scores?.Count() ?? 0; + + if (scoreCount == 0) + { + topScore.Hide(); + return; + } + + topScore.Score = scores.FirstOrDefault(); + topScore.Show(); + + if (scoreCount < 2) + return; + + scoreTable.Scores = scores; + } + protected override void Dispose(bool isDisposing) { getScoresRequest?.Cancel(); From 2525f5bcb787955ab3a315c62143e76bd26825b7 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 9 Mar 2019 23:58:14 +0100 Subject: [PATCH 032/278] Apply most suggestions --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 13 -- .../Visual/TestCaseUserProfileHeader.cs | 8 +- .../Profile/Header/BottomHeaderContainer.cs | 26 +-- .../Profile/Header/CenterHeaderContainer.cs | 138 +++------------- .../Profile/Header/DetailHeaderContainer.cs | 40 ++--- .../Overlays/Profile/Header/DrawableBadge.cs | 46 ++++++ .../Profile/Header/MedalHeaderContainer.cs | 63 ++------ .../Profile/Header/OverlinedInfoContainer.cs | 63 ++++++++ .../Profile/Header/ProfileHeaderButton.cs | 50 ++++++ .../Profile/Header/ProfileHeaderTabControl.cs | 8 +- .../Profile/Header/ProfileMessageButton.cs | 57 +++++++ .../Overlays/Profile/Header/SupporterIcon.cs | 48 +++--- .../Profile/Header/TopHeaderContainer.cs | 34 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 153 +++--------------- osu.Game/Overlays/UserProfileOverlay.cs | 4 +- osu.Game/Users/UserCoverBackground.cs | 47 ++++-- osu.Game/Users/UserPanel.cs | 4 +- 17 files changed, 375 insertions(+), 427 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/DrawableBadge.cs create mode 100644 osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs create mode 100644 osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index d0c4e495b8..3abb2584ce 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -87,8 +87,6 @@ namespace osu.Game.Tests.Visual AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER, false)); - checkSupporterTag(false); - AddStep("Show null dummy", () => profile.ShowUser(new User { Username = @"Null", @@ -104,8 +102,6 @@ namespace osu.Game.Tests.Visual CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" }, api.IsLoggedIn)); - checkSupporterTag(true); - AddStep("Show flyte", () => profile.ShowUser(new User { Username = @"flyte", @@ -118,15 +114,6 @@ namespace osu.Game.Tests.Visual AddStep("Show without reload", profile.Show); } - private void checkSupporterTag(bool isSupporter) - { - AddUntilStep(() => profile.Header.User != null, "wait for load"); - if (isSupporter) - AddAssert("is supporter", () => profile.Header.SupporterTag.Alpha == 1); - else - AddAssert("no supporter", () => profile.Header.SupporterTag.Alpha == 0); - } - private class TestUserProfileOverlay : UserProfileOverlay { public new ProfileHeader Header => base.Header; diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs index 49ffa2d63f..8f36b4dda8 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs @@ -33,9 +33,9 @@ namespace osu.Game.Tests.Visual header = new ProfileHeader(); Add(header); - AddStep("Show offline dummy", () => header.User = TestCaseUserProfile.TEST_USER); + AddStep("Show offline dummy", () => header.User.Value = TestCaseUserProfile.TEST_USER); - AddStep("Show null dummy", () => header.User = new User + AddStep("Show null dummy", () => header.User.Value = new User { Username = "Null" }); @@ -65,11 +65,11 @@ namespace osu.Game.Tests.Visual if (api.IsLoggedIn) { var request = new GetUserRequest(fallback.Id); - request.Success += user => header.User = user; + request.Success += user => header.User.Value = user; api.Queue(request); } else - header.User = fallback; + header.User.Value = fallback; }); } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 7bb1b8acc2..1f9d741b8d 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,32 +18,21 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class BottomHeaderContainer : Container + public class BottomHeaderContainer : CompositeDrawable { private LinkFlowContainer bottomTopLinkContainer; private LinkFlowContainer bottomLinkContainer; private Color4 linkBlue, communityUserGrayGreenLighter; - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - updateDisplay(); - } - } + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours) { - Children = new Drawable[] + AutoSizeAxes = Axes.Y; + User.ValueChanged += e => updateDisplay(e.NewValue); + + InternalChildren = new Drawable[] { new Box { @@ -76,7 +66,7 @@ namespace osu.Game.Overlays.Profile.Header communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; } - private void updateDisplay() + private void updateDisplay(User user) { void bold(SpriteText t) => t.Font = @"Exo2.0-Bold"; void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index ca615ccf4b..b5e04bee9e 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -1,75 +1,48 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class CenterHeaderContainer : Container + public class CenterHeaderContainer : CompositeDrawable { - public readonly BindableBool DetailsVisible = new BindableBool(); + public Action DetailsVisibilityAction; + private bool detailsVisible; private OsuSpriteText followerText; - private ProfileHeaderButton messageButton; private OsuSpriteText levelBadgeText; private Bar levelProgressBar; private OsuSpriteText levelProgressText; - private ProfileHeader.OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; + private OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; - [Resolved(CanBeNull = true)] - private ChannelManager channelManager { get; set; } - - [Resolved(CanBeNull = true)] - private UserProfileOverlay userOverlay { get; set; } - - [Resolved(CanBeNull = true)] - private ChatOverlay chatOverlay { get; set; } - - [Resolved] - private APIAccess apiAccess { get; set; } - - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - updateDisplay(); - } - } + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures) { Container hiddenDetailContainer, expandedDetailContainer; SpriteIcon expandButtonIcon; + ProfileHeaderButton detailsToggleButton; + Height = 60; + User.ValueChanged += e => updateDisplay(e.NewValue); - Children = new Drawable[] + InternalChildren = new Drawable[] { new Box { @@ -118,21 +91,9 @@ namespace osu.Game.Overlays.Profile.Header } } }, - messageButton = new ProfileHeaderButton + new ProfileMessageButton { - Alpha = 0, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_envelope, - FillMode = FillMode.Fit, - Size = new Vector2(50, 14) - }, - } + User = { BindTarget = User } }, } }, @@ -143,12 +104,11 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Y, Padding = new MarginPadding { Vertical = 10 }, Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = new ProfileHeaderButton + Child = detailsToggleButton = new ProfileHeaderButton { RelativeSizeAxes = Axes.Y, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = DetailsVisible.Toggle, Children = new Drawable[] { expandButtonIcon = new SpriteIcon @@ -233,12 +193,12 @@ namespace osu.Game.Overlays.Profile.Header Margin = new MarginPadding { Right = 50 }, Children = new[] { - hiddenDetailGlobal = new ProfileHeader.OverlinedInfoContainer + hiddenDetailGlobal = new OverlinedInfoContainer { Title = "Global Ranking", LineColour = colours.Yellow }, - hiddenDetailCountry = new ProfileHeader.OverlinedInfoContainer + hiddenDetailCountry = new OverlinedInfoContainer { Title = "Country Ranking", LineColour = colours.Yellow @@ -249,76 +209,26 @@ namespace osu.Game.Overlays.Profile.Header } }; - DetailsVisible.ValueChanged += visible => + detailsToggleButton.Action = () => { - expandButtonIcon.Icon = visible.NewValue ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; - hiddenDetailContainer.Alpha = visible.NewValue ? 1 : 0; - expandedDetailContainer.Alpha = visible.NewValue ? 0 : 1; + detailsVisible = !detailsVisible; + expandButtonIcon.Icon = detailsVisible ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; + hiddenDetailContainer.Alpha = detailsVisible ? 1 : 0; + expandedDetailContainer.Alpha = detailsVisible ? 0 : 1; + DetailsVisibilityAction(detailsVisible); }; } - private void updateDisplay() + private void updateDisplay(User user) { followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - if (!user.PMFriendsOnly && apiAccess.LocalUser.Value.Id != user.Id) - { - messageButton.Show(); - messageButton.Action = () => - { - channelManager?.OpenPrivateChannel(user); - userOverlay?.Hide(); - chatOverlay?.Show(); - }; - } - else - { - messageButton.Hide(); - } - levelBadgeText.Text = user.Statistics?.Level.Current.ToString() ?? "0"; levelProgressBar.Length = user.Statistics?.Level.Progress / 100f ?? 0; levelProgressText.Text = user.Statistics?.Level.Progress.ToString("0'%'"); - hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; - hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; - } - - private class ProfileHeaderButton : OsuHoverContainer - { - private readonly Box background; - private readonly Container content; - - protected override Container Content => content; - - protected override IEnumerable EffectTargets => new[] { background }; - - public ProfileHeaderButton() - { - HoverColour = Color4.Black.Opacity(0.75f); - IdleColour = Color4.Black.Opacity(0.7f); - AutoSizeAxes = Axes.X; - - base.Content.Add(new CircularContainer - { - Masking = true, - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - content = new Container - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 10 }, - } - } - }); - } + hiddenDetailGlobal.Content = user.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; + hiddenDetailCountry.Content = user.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; } } } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index a7d21bcdf3..19894f0301 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,34 +18,23 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class DetailHeaderContainer : Container + public class DetailHeaderContainer : CompositeDrawable { private ProfileHeader.HasTooltipContainer totalPlayTimeTooltip; - private ProfileHeader.OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; + private OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; private readonly Dictionary scoreRankInfos = new Dictionary(); - private ProfileHeader.OverlinedInfoContainer detailGlobalRank, detailCountryRank; + private OverlinedInfoContainer detailGlobalRank, detailCountryRank; private RankGraph rankGraph; - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - updateDisplay(); - } - } + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours) { - Children = new Drawable[] + AutoSizeAxes = Axes.Y; + User.ValueChanged += e => updateDisplay(e.NewValue); + + InternalChildren = new Drawable[] { new Box { @@ -79,18 +69,18 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Both, TooltipText = "0 hours", - Child = totalPlayTimeInfo = new ProfileHeader.OverlinedInfoContainer + Child = totalPlayTimeInfo = new OverlinedInfoContainer { Title = "Total Play Time", LineColour = colours.Yellow, }, }, - medalInfo = new ProfileHeader.OverlinedInfoContainer + medalInfo = new OverlinedInfoContainer { Title = "Medals", LineColour = colours.GreenLight, }, - ppInfo = new ProfileHeader.OverlinedInfoContainer + ppInfo = new OverlinedInfoContainer { Title = "pp", LineColour = colours.Red, @@ -135,12 +125,12 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 20), Children = new Drawable[] { - detailGlobalRank = new ProfileHeader.OverlinedInfoContainer(true, 110) + detailGlobalRank = new OverlinedInfoContainer(true, 110) { Title = "Global Ranking", LineColour = colours.Yellow, }, - detailCountryRank = new ProfileHeader.OverlinedInfoContainer(false, 110) + detailCountryRank = new OverlinedInfoContainer(false, 110) { Title = "Country Ranking", LineColour = colours.Yellow, @@ -154,7 +144,7 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay() + private void updateDisplay(User user) { medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToString("#,##0") ?? "0"; diff --git a/osu.Game/Overlays/Profile/Header/DrawableBadge.cs b/osu.Game/Overlays/Profile/Header/DrawableBadge.cs new file mode 100644 index 0000000000..75a8f4e415 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/DrawableBadge.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class DrawableBadge : CompositeDrawable, IHasTooltip + { + public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); + + private readonly Badge badge; + + public DrawableBadge(Badge badge) + { + this.badge = badge; + Size = DRAWABLE_BADGE_SIZE; + } + + [BackgroundDependencyLoader] + private void load(LargeTextureStore textures) + { + InternalChild = new Sprite + { + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(badge.ImageUrl), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + InternalChild.FadeInFromZero(200); + } + + public string TooltipText => badge.Description; + } +} diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 45c1e1e208..69b1203b9f 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -2,14 +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.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Users; using osuTK; @@ -17,31 +15,20 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class MedalHeaderContainer : Container + public class MedalHeaderContainer : CompositeDrawable { private FillFlowContainer badgeFlowContainer; - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - updateDisplay(); - } - } + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours) { Alpha = 0; - Children = new Drawable[] + AutoSizeAxes = Axes.Y; + User.ValueChanged += e => updateDisplay(e.NewValue); + + InternalChildren = new Drawable[] { new Box { @@ -76,9 +63,9 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay() + private void updateDisplay(User user) { - var badges = User.Badges; + var badges = user.Badges; badgeFlowContainer.Clear(); if (badges?.Length > 0) { @@ -100,37 +87,5 @@ namespace osu.Game.Overlays.Profile.Header Hide(); } } - - private class DrawableBadge : CompositeDrawable, IHasTooltip - { - public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); - - private readonly Badge badge; - - public DrawableBadge(Badge badge) - { - this.badge = badge; - Size = DRAWABLE_BADGE_SIZE; - } - - [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) - { - InternalChild = new Sprite - { - FillMode = FillMode.Fit, - RelativeSizeAxes = Axes.Both, - Texture = textures.Get(badge.ImageUrl), - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - InternalChild.FadeInFromZero(200); - } - - public string TooltipText => badge.Description; - } } } diff --git a/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs new file mode 100644 index 0000000000..6d15f96eea --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs @@ -0,0 +1,63 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class OverlinedInfoContainer : CompositeDrawable + { + private readonly Circle line; + private readonly OsuSpriteText title, content; + + public string Title + { + set => title.Text = value; + } + + public string Content + { + set => content.Text = value; + } + + public Color4 LineColour + { + set => line.Colour = value; + } + + public OverlinedInfoContainer(bool big = false, int minimumWidth = 60) + { + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + line = new Circle + { + RelativeSizeAxes = Axes.X, + Height = 4, + }, + title = new OsuSpriteText + { + Font = OsuFont.GetFont(size: big ? 14 : 12, weight: FontWeight.Bold) + }, + content = new OsuSpriteText + { + Font = OsuFont.GetFont(size: big ? 40 : 18, weight: FontWeight.Light) + }, + new Container //Add a minimum size to the FillFlowContainer + { + Width = minimumWidth, + } + } + }; + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs new file mode 100644 index 0000000000..6d9ab7a4d8 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs @@ -0,0 +1,50 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Containers; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class ProfileHeaderButton : OsuHoverContainer + { + private readonly Box background; + private readonly Container content; + + protected override Container Content => content; + + protected override IEnumerable EffectTargets => new[] { background }; + + public ProfileHeaderButton() + { + HoverColour = Color4.Black.Opacity(0.75f); + IdleColour = Color4.Black.Opacity(0.7f); + AutoSizeAxes = Axes.X; + + base.Content.Add(new CircularContainer + { + Masking = true, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + content = new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 10 }, + } + } + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index a8e50e00fe..e7c9676550 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -93,11 +93,11 @@ namespace osu.Game.Overlays.Profile.Header { text = new OsuSpriteText { - Margin = new MarginPadding { Bottom = 15 }, + Margin = new MarginPadding { Bottom = 10 }, Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, Text = value, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) + Font = OsuFont.GetFont() }, bar = new Circle { @@ -134,7 +134,7 @@ namespace osu.Game.Overlays.Profile.Header { text.FadeColour(AccentColour, 120, Easing.InQuad); bar.ResizeHeightTo(0, 120, Easing.InQuad); - text.Font = text.Font.With(Typeface.Exo, weight: FontWeight.Medium); + text.Font = text.Font.With(weight: FontWeight.Medium); } private void onActivated(bool fake = false) @@ -142,7 +142,7 @@ namespace osu.Game.Overlays.Profile.Header text.FadeColour(Color4.White, 120, Easing.InQuad); bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); if (!fake) - text.Font = text.Font.With(Typeface.Exo, weight: FontWeight.Bold); + text.Font = text.Font.With(weight: FontWeight.Bold); } } } diff --git a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs new file mode 100644 index 0000000000..a14c0324d7 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs @@ -0,0 +1,57 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.Chat; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class ProfileMessageButton : ProfileHeaderButton + { + public readonly Bindable User = new Bindable(); + + [Resolved(CanBeNull = true)] + private ChannelManager channelManager { get; set; } + + [Resolved(CanBeNull = true)] + private UserProfileOverlay userOverlay { get; set; } + + [Resolved(CanBeNull = true)] + private ChatOverlay chatOverlay { get; set; } + + [Resolved] + private APIAccess apiAccess { get; set; } + + public ProfileMessageButton() + { + Content.Alpha = 0; + RelativeSizeAxes = Axes.Y; + + Child = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_envelope, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }; + + Action = () => + { + if (!Content.IsPresent) return; + + channelManager?.OpenPrivateChannel(User.Value); + userOverlay?.Hide(); + chatOverlay?.Show(); + }; + + User.ValueChanged += e => Content.Alpha = !e.NewValue.PMFriendsOnly && apiAccess.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs index d7e25e32c2..04d6db8b3c 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -10,10 +10,11 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class SupporterIcon : CircularContainer, IHasTooltip + public class SupporterIcon : CompositeDrawable, IHasTooltip { private readonly Box background; private readonly FillFlowContainer iconContainer; + private readonly CircularContainer content; public string TooltipText => "osu!supporter"; @@ -23,11 +24,11 @@ namespace osu.Game.Overlays.Profile.Header { if (value == 0) { - Hide(); + content.Hide(); } else { - Show(); + content.Show(); iconContainer.Clear(); for (int i = 0; i < value; i++) { @@ -38,43 +39,38 @@ namespace osu.Game.Overlays.Profile.Header Icon = FontAwesome.fa_heart, }); } + + iconContainer.Padding = new MarginPadding { Horizontal = DrawHeight / 2 }; } } } public SupporterIcon() { - Masking = true; AutoSizeAxes = Axes.X; - Hide(); - Children = new Drawable[] + InternalChild = content = new CircularContainer { - background = new Box { RelativeSizeAxes = Axes.Both }, - iconContainer = new FillFlowContainer + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Masking = true, + Alpha = 0, + Children = new Drawable[] { - Direction = FillDirection.Horizontal, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Height = 0.6f, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + background = new Box { RelativeSizeAxes = Axes.Both }, + iconContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Height = 0.6f, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } } }; } - public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) - { - bool invalid = base.Invalidate(invalidation, source, shallPropagate); - - if ((invalidation & Invalidation.DrawSize) != 0) - { - iconContainer.Padding = new MarginPadding { Horizontal = DrawHeight / 2 }; - } - - return invalid; - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 13a7951170..8e4d72c702 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,9 +15,9 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class TopHeaderContainer : Container + public class TopHeaderContainer : CompositeDrawable { - public SupporterIcon SupporterTag; + private SupporterIcon supporterTag; private UpdateableAvatar avatar; private OsuSpriteText usernameText; private ExternalLinkButton openUserExternally; @@ -27,26 +28,15 @@ namespace osu.Game.Overlays.Profile.Header private const float avatar_size = 110; - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - updateDisplay(); - } - } + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours) { - Children = new Drawable[] + Height = 150; + User.ValueChanged += e => updateDisplay(e.NewValue); + + InternalChildren = new Drawable[] { new Box { @@ -109,7 +99,7 @@ namespace osu.Game.Overlays.Profile.Header TextSize = 18, Font = "Exo2.0-Regular" }, - SupporterTag = new SupporterIcon + supporterTag = new SupporterIcon { Height = 20, Margin = new MarginPadding { Top = 5 } @@ -161,14 +151,14 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay() + private void updateDisplay(User user) { - avatar.User = User; + avatar.User = user; usernameText.Text = user.Username; openUserExternally.Link = $@"https://osu.ppy.sh/users/{user.Id}"; userFlag.Country = user.Country; userCountryText.Text = user.Country?.FullName ?? "Alien"; - SupporterTag.SupporterLevel = user.SupportLevel; + supporterTag.SupporterLevel = user.SupportLevel; titleText.Text = user.Title; titleText.Colour = OsuColour.FromHex(user.Colour ?? "fff"); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index fdb515270b..988fa3afd9 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -2,43 +2,31 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osuTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; using osu.Framework.Bindables; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Profile { public class ProfileHeader : Container { - private readonly Container coverContainer; - private readonly OsuSpriteText coverInfoText; + private readonly UserCoverBackground coverContainer; + private readonly ScreenTitle coverTitle; private readonly ProfileHeaderTabControl infoTabControl; - private readonly TopHeaderContainer topHeaderContainer; - public SupporterIcon SupporterTag => topHeaderContainer.SupporterTag; - - private readonly CenterHeaderContainer centerHeaderContainer; - public readonly BindableBool DetailsVisible = new BindableBool(); - - private readonly DetailHeaderContainer detailHeaderContainer; - private readonly MedalHeaderContainer medalHeaderContainer; - private readonly BottomHeaderContainer bottomHeaderContainer; - private const float cover_height = 150; private const float cover_info_height = 75; public ProfileHeader() { + CenterHeaderContainer centerHeaderContainer; + DetailHeaderContainer detailHeaderContainer; Container expandedDetailContainer; FillFlowContainer hiddenDetailContainer, headerDetailContainer; SpriteIcon expandButtonIcon; @@ -48,19 +36,10 @@ namespace osu.Game.Overlays.Profile Children = new Drawable[] { - coverContainer = new Container + coverContainer = new UserCoverBackground { RelativeSizeAxes = Axes.X, Height = cover_height, - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.75f)) - }, - } }, new Container { @@ -73,25 +52,10 @@ namespace osu.Game.Overlays.Profile Depth = -float.MaxValue, Children = new Drawable[] { - new FillFlowContainer + coverTitle = new ScreenTitle { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] - { - new OsuSpriteText - { - Text = "Player ", - Font = "Exo2.0-Regular", - TextSize = 30 - }, - coverInfoText = new OsuSpriteText - { - Text = "Info", - Font = "Exo2.0-Regular", - TextSize = 30 - } - } + Title = "Player ", + Page = "Info" }, infoTabControl = new ProfileHeaderTabControl { @@ -112,30 +76,30 @@ namespace osu.Game.Overlays.Profile Direction = FillDirection.Vertical, Children = new Drawable[] { - topHeaderContainer = new TopHeaderContainer + new TopHeaderContainer { RelativeSizeAxes = Axes.X, - Height = 150, + User = { BindTarget = User }, }, centerHeaderContainer = new CenterHeaderContainer { RelativeSizeAxes = Axes.X, - Height = 60, + User = { BindTarget = User }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + User = { BindTarget = User }, }, - medalHeaderContainer = new MedalHeaderContainer + new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + User = { BindTarget = User }, }, - bottomHeaderContainer = new BottomHeaderContainer + new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + User = { BindTarget = User }, }, } } @@ -144,99 +108,28 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Info"); infoTabControl.AddItem("Modding"); - centerHeaderContainer.DetailsVisible.BindTo(DetailsVisible); - DetailsVisible.ValueChanged += visible => detailHeaderContainer.Alpha = visible.NewValue ? 0 : 1; + centerHeaderContainer.DetailsVisibilityAction = visible => detailHeaderContainer.Alpha = visible ? 0 : 1; + User.ValueChanged += e => updateDisplay(e.NewValue); } [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures) { - coverInfoText.Colour = colours.CommunityUserGreen; + coverTitle.AccentColour = colours.CommunityUserGreen; infoTabControl.AccentColour = colours.CommunityUserGreen; } - private User user; + public Bindable User = new Bindable(); - public User User + private void updateDisplay(User user) { - get => user; - set - { - medalHeaderContainer.User = detailHeaderContainer.User = bottomHeaderContainer.User = - centerHeaderContainer.User = topHeaderContainer.User = user = value; - updateDisplay(); - } - } - - private void updateDisplay() - { - coverContainer.RemoveAll(d => d is UserCoverBackground); - LoadComponentAsync(new UserCoverBackground(user) - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(200), - Depth = float.MaxValue, - }, coverContainer.Add); + coverContainer.User = user; } public class HasTooltipContainer : Container, IHasTooltip { public string TooltipText { get; set; } } - - public class OverlinedInfoContainer : CompositeDrawable - { - private readonly Circle line; - private readonly OsuSpriteText title, content; - - public string Title - { - set => title.Text = value; - } - - public string Content - { - set => content.Text = value; - } - - public Color4 LineColour - { - set => line.Colour = value; - } - - public OverlinedInfoContainer(bool big = false, int minimumWidth = 60) - { - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - Direction = FillDirection.Vertical, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - line = new Circle - { - RelativeSizeAxes = Axes.X, - Height = 4, - }, - title = new OsuSpriteText - { - Font = OsuFont.GetFont(size: big ? 14 : 12, weight: FontWeight.Bold) - }, - content = new OsuSpriteText - { - Font = OsuFont.GetFont(size: big ? 40 : 18, weight: FontWeight.Light) - }, - new Container //Add a minimum size to the FillFlowContainer - { - Width = minimumWidth, - } - } - }; - } - } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 60e2921127..9b6e34d399 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -81,7 +81,7 @@ namespace osu.Game.Overlays Show(); - if (user.Id == Header?.User?.Id) + if (user.Id == Header?.User.Value?.Id) return; userReq?.Cancel(); @@ -167,7 +167,7 @@ namespace osu.Game.Overlays private void userLoadComplete(User user) { - Header.User = user; + Header.User.Value = user; if (user.ProfileOrder != null) { diff --git a/osu.Game/Users/UserCoverBackground.cs b/osu.Game/Users/UserCoverBackground.cs index 4c72762498..d037f809b4 100644 --- a/osu.Game/Users/UserCoverBackground.cs +++ b/osu.Game/Users/UserCoverBackground.cs @@ -1,30 +1,51 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osuTK.Graphics; namespace osu.Game.Users { - public class UserCoverBackground : Sprite + public class UserCoverBackground : ModelBackedDrawable { - private readonly User user; - - public UserCoverBackground(User user) + public User User { - this.user = user; + get => Model; + set => Model = value; } - [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) - { - if (textures == null) - throw new ArgumentNullException(nameof(textures)); + [Resolved] + private LargeTextureStore textures { get; set; } - if (!string.IsNullOrEmpty(user.CoverUrl)) - Texture = textures.Get(user.CoverUrl); + protected override Drawable CreateDrawable(User user) + { + if (user == null) + { + return new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.75f)) + }; + } + else + { + return new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(user.CoverUrl), + FillMode = FillMode.Fill, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + OnLoadComplete = d => d.FadeInFromZero(400), + }; + } } } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index cebbc74d50..def967e69b 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -73,12 +73,12 @@ namespace osu.Game.Users Children = new Drawable[] { - new DelayedLoadWrapper(new UserCoverBackground(user) + new DelayedLoadWrapper(new UserCoverBackground { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - FillMode = FillMode.Fill, + User = user, OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out) }, 300) { RelativeSizeAxes = Axes.Both }, new Box From 315788c97535344f84988c12a63777fbc5032620 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Mar 2019 15:11:01 +0900 Subject: [PATCH 033/278] Rename a few classes --- osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs | 6 +++--- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- .../Scores/{ScoreTextLine.cs => ScoreTableHeader.cs} | 4 ++-- .../Scores/{ScoreTableLine.cs => ScoreTableRow.cs} | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename osu.Game/Overlays/BeatmapSet/Scores/{ScoreTextLine.cs => ScoreTableHeader.cs} (94%) rename osu.Game/Overlays/BeatmapSet/Scores/{ScoreTableLine.cs => ScoreTableRow.cs} (98%) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index a2a9f9a01b..d7396c8839 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.Both, Alpha = 0, }, - new DrawableScoreData(index, score, maxModsAmount), + new ScoreRow(index, score, maxModsAmount), }; if (index % 2 != 0) @@ -118,9 +118,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private class DrawableScoreData : ScoreTableLine + private class ScoreRow : ScoreTableRow { - public DrawableScoreData(int index, APIScoreInfo score, int maxModsAmount) + public ScoreRow(int index, APIScoreInfo score, int maxModsAmount) : base(maxModsAmount) { SpriteText scoreText; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 4723fcaf2b..5d248c5501 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores maxModsAmount = scoreModsAmount; } - scoresFlow.Add(new ScoreTextLine(maxModsAmount)); + scoresFlow.Add(new ScoreTableHeader(maxModsAmount)); int index = 0; foreach (var s in value) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs similarity index 94% rename from osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs rename to osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs index 9e201bd98d..544bf34ec5 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTextLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs @@ -5,9 +5,9 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTextLine : ScoreTableLine + public class ScoreTableHeader : ScoreTableRow { - public ScoreTextLine(int maxModsAmount) + public ScoreTableHeader(int maxModsAmount) : base(maxModsAmount) { RankContainer.Add(new ScoreText diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs similarity index 98% rename from osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs rename to osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs index 5c4723eae1..3a48a0cca1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableLine.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTableLine : GridContainer + public class ScoreTableRow : GridContainer { private const float rank_position = 30; private const float drawable_rank_position = 45; @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected readonly Container PPContainer; protected readonly Container ModsContainer; - public ScoreTableLine(int maxModsAmount) + public ScoreTableRow(int maxModsAmount) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From 41d25c7d19d6d7babd2c0194d77fc68bf8dcfc2b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 20 Mar 2019 17:15:21 +0900 Subject: [PATCH 034/278] Fix post-merge errors --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 6c90e192ac..79858a9ccb 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly LoadingAnimation loadingAnimation; [Resolved] - private APIAccess api { get; set; } + private IAPIProvider api { get; set; } public ScoresContainer() { @@ -71,7 +71,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(APIAccess api, OsuColour colours) + private void load(OsuColour colours) { background.Colour = colours.Gray2; updateDisplay(); From f7016e1d2c81b4ab675c3a654ca3695bbf1265b5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 20 Mar 2019 17:15:38 +0900 Subject: [PATCH 035/278] Rename DrawableScore --- osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs | 2 +- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- .../Scores/{DrawableScore.cs => ScoreTableScore.cs} | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Overlays/BeatmapSet/Scores/{DrawableScore.cs => ScoreTableScore.cs} (98%) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs index 20609dc595..58ccaf9dfa 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual { typeof(Header), typeof(ClickableUserContainer), - typeof(DrawableScore), + typeof(ScoreTableScore), typeof(DrawableTopScore), typeof(ScoresContainer), typeof(AuthorInfo), diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 5d248c5501..aacbc12cd8 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores int index = 0; foreach (var s in value) - scoresFlow.Add(new DrawableScore(index++, s, maxModsAmount)); + scoresFlow.Add(new ScoreTableScore(index++, s, maxModsAmount)); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs similarity index 98% rename from osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs rename to osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs index d7396c8839..a54770fb39 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class DrawableScore : Container + public class ScoreTableScore : Container { private const int fade_duration = 100; private const int text_size = 14; @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box hoveredBackground; private readonly Box background; - public DrawableScore(int index, APIScoreInfo score, int maxModsAmount) + public ScoreTableScore(int index, APIScoreInfo score, int maxModsAmount) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From e93311fdc9e2372e262e5fb9f4cd496ec53f5798 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 22 Mar 2019 19:01:32 +0900 Subject: [PATCH 036/278] DI facade --- .../Graphics/Containers/FacadeContainer.cs | 30 +++++++++++++++++++ osu.Game/Screens/Play/PlayerLoader.cs | 14 ++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Graphics/Containers/FacadeContainer.cs diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs new file mode 100644 index 0000000000..7d7a4b0680 --- /dev/null +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Game.Screens.Menu; +using osuTK; + +namespace osu.Game.Graphics.Containers +{ + public class FacadeContainer : Container + { + [Cached] + private Facade facade; + + public FacadeContainer() + { + facade = new Facade(); + } + + public void SetLogo(OsuLogo logo) + { + facade.Size = new Vector2(logo.SizeForFlow); + } + } + + public class Facade : Container + { + } +} diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index e9ee5d3fa8..878c2541e9 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -14,6 +14,7 @@ using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Menu; @@ -32,7 +33,7 @@ namespace osu.Game.Screens.Play private Player player; - private Container content; + private FacadeContainer content; private BeatmapMetadataDisplay info; @@ -59,7 +60,7 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - InternalChild = content = new Container + InternalChild = content = new FacadeContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -153,6 +154,8 @@ namespace osu.Game.Screens.Play logo.FadeIn(350); logo.Delay(resuming ? 0 : 500).MoveToOffset(new Vector2(0, -0.24f), 500, Easing.InOutExpo); + + content.SetLogo(logo); } protected override void LoadComplete() @@ -302,6 +305,8 @@ namespace osu.Game.Screens.Play private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; + private FillFlowContainer fillFlowContainer; + private FacadeContainer facadeContainer; public bool Loading { @@ -326,14 +331,14 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load() + private void load(Facade facade) { var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); AutoSizeAxes = Axes.Both; Children = new Drawable[] { - new FillFlowContainer + fillFlowContainer = new FillFlowContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopCentre, @@ -341,6 +346,7 @@ namespace osu.Game.Screens.Play Direction = FillDirection.Vertical, Children = new Drawable[] { + facade, new OsuSpriteText { Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)), From 6e98a8dd7c15ff372a39ebf9b7785b0c6e16a755 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 22 Mar 2019 20:01:58 +0900 Subject: [PATCH 037/278] Initial implementation --- osu.Game.Tests/Visual/TestCasePlayerLoader.cs | 10 +++- .../Graphics/Containers/FacadeContainer.cs | 53 ++++++++++++++++++- osu.Game/Screens/Play/PlayerLoader.cs | 13 +++-- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs index 2bc416f7f4..ad0965b4d6 100644 --- a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs @@ -7,7 +7,9 @@ using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Screens; +using osu.Game.Screens.Menu; using osu.Game.Screens.Play; +using osuTK; namespace osu.Game.Tests.Visual { @@ -16,6 +18,9 @@ namespace osu.Game.Tests.Visual private PlayerLoader loader; private readonly ScreenStack stack; + [Cached] + private OsuLogo logo; + [Cached] private BackgroundScreenStack backgroundStack; @@ -23,6 +28,7 @@ namespace osu.Game.Tests.Visual { InputManager.Add(backgroundStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }); InputManager.Add(stack = new ScreenStack { RelativeSizeAxes = Axes.Both }); + InputManager.Add(logo = new OsuLogo()); } [BackgroundDependencyLoader] @@ -30,6 +36,8 @@ namespace osu.Game.Tests.Visual { Beatmap.Value = new DummyWorkingBeatmap(game); + AddStep("Reset logo position", () => logo = new OsuLogo { Position = new Vector2(0, 0) }); + AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player { AllowPause = false, @@ -57,8 +65,6 @@ namespace osu.Game.Tests.Visual AllowLeadIn = false, AllowResults = false, })); - - Scheduler.AddDelayed(() => slow.Ready = true, 5000); }); AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen()); diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index 7d7a4b0680..e39fba64ce 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Screens.Menu; using osuTK; @@ -13,14 +14,62 @@ namespace osu.Game.Graphics.Containers [Cached] private Facade facade; + private OsuLogo logo; + + private bool tracking; + private bool smoothTransform; + public FacadeContainer() { facade = new Facade(); } - public void SetLogo(OsuLogo logo) + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); + + public void SetLogo(OsuLogo logo, bool resuming, double transformDelay) { - facade.Size = new Vector2(logo.SizeForFlow); + if (logo != null) + { + facade.Size = new Vector2(logo.SizeForFlow * 0.3f); + this.logo = logo; + Scheduler.AddDelayed(() => + { + tracking = true; + smoothTransform = !resuming; + }, transformDelay); + } + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + facade.Size = new Vector2(logo.SizeForFlow * 0.3f); + + if (!tracking) + return; + + logo.RelativePositionAxes = Axes.None; + + bool childrenLoaded = true; + + foreach (var d in Children) + { + if (!d.IsAlive) + childrenLoaded = false; + } + + if (smoothTransform && childrenLoaded) + { + // Our initial movement to the tracking location should be smooth. + Schedule(() => logo.MoveTo(logoTrackingPosition, 500, Easing.InOutExpo)); + smoothTransform = false; + } + else if (logo.Transforms.Count == 0) + { + // If all transforms have finished playing, the logo constantly track the position of the facade. + logo.Position = logoTrackingPosition; + } } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 878c2541e9..97249ee6cd 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -149,13 +149,13 @@ namespace osu.Game.Screens.Play { base.LogoArriving(logo, resuming); - logo.ScaleTo(new Vector2(0.15f), 300, Easing.In); - logo.MoveTo(new Vector2(0.5f), 300, Easing.In); + const double duration = 300; + + logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); + logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); - logo.Delay(resuming ? 0 : 500).MoveToOffset(new Vector2(0, -0.24f), 500, Easing.InOutExpo); - - content.SetLogo(logo); + content.SetLogo(logo, resuming, duration); } protected override void LoadComplete() @@ -335,6 +335,9 @@ namespace osu.Game.Screens.Play { var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); + facade.Anchor = Anchor.TopCentre; + facade.Origin = Anchor.TopCentre; + AutoSizeAxes = Axes.Both; Children = new Drawable[] { From d37968d88df2ad6f6f0a6f64596212df28bfabde Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sun, 24 Mar 2019 15:18:38 +0900 Subject: [PATCH 038/278] Add better test for facade containers --- .../Visual/TestCaseFacadeContainer.cs | 113 ++++++++++++++++++ .../Graphics/Containers/FacadeContainer.cs | 33 +++-- osu.Game/Screens/Play/PlayerLoader.cs | 46 +++---- 3 files changed, 152 insertions(+), 40 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseFacadeContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs new file mode 100644 index 0000000000..3063a4ca3f --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -0,0 +1,113 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Configuration; +using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens; +using osu.Game.Screens.Menu; +using osu.Game.Screens.Play; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseFacadeContainer : ScreenTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(PlayerLoader), + typeof(Player), + typeof(Facade), + }; + + [Cached] + private OsuLogo logo; + + private readonly Bindable uiScale = new Bindable(); + + private OsuScreen baseScreen; + + public TestCaseFacadeContainer() + { + Add(logo = new OsuLogo()); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + baseScreen = null; + config.BindWith(OsuSetting.UIScale, uiScale); + AddSliderStep("Adjust scale", 1f, 1.5f, 1f, v => uiScale.Value = v); + AddToggleStep("Toggle mods", b => { Beatmap.Value.Mods.Value = b ? Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }) : Enumerable.Empty(); }); + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("Null screens", () => baseScreen = null); + } + + [Test] + public void PlayerLoaderTest() + { + AddStep("Add new playerloader", () => LoadScreen(baseScreen = new TestPlayerLoader(() => new TestPlayer + { + AllowPause = false, + AllowLeadIn = false, + AllowResults = false, + }))); + } + + [Test] + public void MainMenuTest() + { + AddStep("Add new Main Menu", () => LoadScreen(baseScreen = new MainMenu())); + } + + private class TestFacadeContainer : FacadeContainer + { + protected override Facade CreateFacade() => new Facade + { + Colour = Color4.Tomato, + Alpha = 0.35f, + Child = new Box + { + Colour = Color4.Tomato, + RelativeSizeAxes = Axes.Both, + }, + }; + } + + private class TestPlayerLoader : PlayerLoader + { + public TestPlayerLoader(Func player) + : base(player) + { + } + + protected override FacadeContainer CreateFacadeContainer() => new TestFacadeContainer(); + } + + private class TestPlayer : Player + { + [BackgroundDependencyLoader] + private void load() + { + // Never finish loading + while (true) + Thread.Sleep(1); + } + } + } +} diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index e39fba64ce..d7fae8887f 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -19,9 +20,11 @@ namespace osu.Game.Graphics.Containers private bool tracking; private bool smoothTransform; + protected virtual Facade CreateFacade() => new Facade(); + public FacadeContainer() { - facade = new Facade(); + facade = CreateFacade(); } private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); @@ -44,30 +47,26 @@ namespace osu.Game.Graphics.Containers { base.UpdateAfterChildren(); - facade.Size = new Vector2(logo.SizeForFlow * 0.3f); - - if (!tracking) + if (logo == null) return; - logo.RelativePositionAxes = Axes.None; + facade.Size = new Vector2(logo.SizeForFlow * 0.3f); - bool childrenLoaded = true; - - foreach (var d in Children) - { - if (!d.IsAlive) - childrenLoaded = false; - } - - if (smoothTransform && childrenLoaded) + if (smoothTransform && facade.IsLoaded && logo.Transforms.Count == 0) { // Our initial movement to the tracking location should be smooth. - Schedule(() => logo.MoveTo(logoTrackingPosition, 500, Easing.InOutExpo)); - smoothTransform = false; + Schedule(() => + { + facade.Size = new Vector2(logo.SizeForFlow * 0.3f); + logo.RelativePositionAxes = Axes.None; + logo.MoveTo(logoTrackingPosition, 500, Easing.InOutExpo); + smoothTransform = false; + }); } - else if (logo.Transforms.Count == 0) + else if (facade.IsLoaded && logo.Transforms.Count == 0) { // If all transforms have finished playing, the logo constantly track the position of the facade. + logo.RelativePositionAxes = Axes.None; logo.Position = logoTrackingPosition; } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 97249ee6cd..5817e11277 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play private FacadeContainer content; + protected virtual FacadeContainer CreateFacadeContainer() => new FacadeContainer(); + private BeatmapMetadataDisplay info; private bool hideOverlays; @@ -60,32 +62,30 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - InternalChild = content = new FacadeContainer + InternalChild = content = CreateFacadeContainer(); + content.Anchor = Anchor.Centre; + content.Origin = Anchor.Centre; + content.RelativeSizeAxes = Axes.Both; + content.Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + info = new BeatmapMetadataDisplay(Beatmap.Value) { - info = new BeatmapMetadataDisplay(Beatmap.Value) + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding(25), + Children = new PlayerSettingsGroup[] { - Alpha = 0, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding(25), - Children = new PlayerSettingsGroup[] - { - VisualSettings = new VisualSettings(), - new InputSettings() - } + VisualSettings = new VisualSettings(), + new InputSettings() } } }; From bc16a82494582f0d6c3f294ae3dc7f89e9cd07fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Mar 2019 17:39:53 +0900 Subject: [PATCH 039/278] Move osu! cursor to its own class --- .../UI/Cursor/GameplayCursorContainer.cs | 140 ----------------- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 148 ++++++++++++++++++ 2 files changed, 148 insertions(+), 140 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs index 8c6723f5be..b64561e4f7 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs @@ -1,19 +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.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; -using osu.Game.Beatmaps; -using osu.Game.Configuration; -using osu.Game.Skinning; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI.Cursor { @@ -88,136 +79,5 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint); ActiveCursor.ScaleTo(0.8f, 450, Easing.OutQuint); } - - public class OsuCursor : SkinReloadableDrawable - { - private bool cursorExpand; - - private Bindable cursorScale; - private Bindable autoCursorScale; - private readonly IBindable beatmap = new Bindable(); - - private Container expandTarget; - private Drawable scaleTarget; - - public OsuCursor() - { - Origin = Anchor.Centre; - Size = new Vector2(28); - } - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - cursorExpand = skin.GetValue(s => s.CursorExpand ?? true); - } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config, IBindable beatmap) - { - InternalChild = expandTarget = new Container - { - RelativeSizeAxes = Axes.Both, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Child = scaleTarget = new SkinnableDrawable("cursor", _ => new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - BorderThickness = Size.X / 6, - BorderColour = Color4.White, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Pink.Opacity(0.5f), - Radius = 5, - }, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, - }, - new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - BorderThickness = Size.X / 3, - BorderColour = Color4.White.Opacity(0.5f), - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, - }, - }, - }, - new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.1f), - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, - }, - }, - } - }, restrictSize: false) - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - } - }; - - this.beatmap.BindTo(beatmap); - this.beatmap.ValueChanged += _ => calculateScale(); - - cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); - cursorScale.ValueChanged += _ => calculateScale(); - - autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); - autoCursorScale.ValueChanged += _ => calculateScale(); - - calculateScale(); - } - - private void calculateScale() - { - float scale = (float)cursorScale.Value; - - if (autoCursorScale.Value && beatmap.Value != null) - { - // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. - scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY); - } - - scaleTarget.Scale = new Vector2(scale); - } - - private const float pressed_scale = 1.2f; - private const float released_scale = 1f; - - public void Expand() - { - if (!cursorExpand) return; - - expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 100, Easing.OutQuad); - } - - public void Contract() => expandTarget.ScaleTo(released_scale, 100, Easing.OutQuad); - } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs new file mode 100644 index 0000000000..ecdafb0fa2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -0,0 +1,148 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Skinning; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.UI.Cursor +{ + public class OsuCursor : SkinReloadableDrawable + { + private bool cursorExpand; + + private Bindable cursorScale; + private Bindable autoCursorScale; + private readonly IBindable beatmap = new Bindable(); + + private Container expandTarget; + private Drawable scaleTarget; + + public OsuCursor() + { + Origin = Anchor.Centre; + Size = new Vector2(28); + } + + protected override void SkinChanged(ISkinSource skin, bool allowFallback) + { + cursorExpand = skin.GetValue(s => s.CursorExpand ?? true); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, IBindable beatmap) + { + InternalChild = expandTarget = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Child = scaleTarget = new SkinnableDrawable("cursor", _ => new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = Size.X / 6, + BorderColour = Color4.White, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Pink.Opacity(0.5f), + Radius = 5, + }, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true, + }, + new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = Size.X / 3, + BorderColour = Color4.White.Opacity(0.5f), + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true, + }, + }, + }, + new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.1f), + Masking = true, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + }, + }, + } + }, restrictSize: false) + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + } + }; + + this.beatmap.BindTo(beatmap); + this.beatmap.ValueChanged += _ => calculateScale(); + + cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); + cursorScale.ValueChanged += _ => calculateScale(); + + autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); + autoCursorScale.ValueChanged += _ => calculateScale(); + + calculateScale(); + } + + private void calculateScale() + { + float scale = (float)cursorScale.Value; + + if (autoCursorScale.Value && beatmap.Value != null) + { + // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. + scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY); + } + + scaleTarget.Scale = new Vector2(scale); + } + + private const float pressed_scale = 1.2f; + private const float released_scale = 1f; + + public void Expand() + { + if (!cursorExpand) return; + + expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 100, Easing.OutQuad); + } + + public void Contract() => expandTarget.ScaleTo(released_scale, 100, Easing.OutQuad); + } +} From 8ad4009c33d5c0f9984d85cfb26ed69dcf0b6eec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Mar 2019 19:04:07 +0900 Subject: [PATCH 040/278] osu! resume overlay --- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 105 +++++++++++++++++++ osu.Game/Screens/Play/ResumeOverlay.cs | 74 +++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs create mode 100644 osu.Game/Screens/Play/ResumeOverlay.cs diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs new file mode 100644 index 0000000000..c2000131db --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -0,0 +1,105 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Rulesets.Osu.UI.Cursor; +using osu.Game.Screens.Play; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.UI +{ + public class OsuResumeOverlay : ResumeOverlay + { + private OsuClickToResumeCursor clickToResumeCursor; + + private GameplayCursorContainer localCursorContainer; + + public override CursorContainer LocalCursor => State == Visibility.Visible ? localCursorContainer : null; + + protected override string Message => "Click the orange cursor to resume"; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Add(clickToResumeCursor = new OsuClickToResumeCursor { ResumeRequested = Resume }); + } + + public override void Show() + { + base.Show(); + clickToResumeCursor.ShowAt(GameplayCursor.ActiveCursor.Position); + Add(localCursorContainer = new GameplayCursorContainer()); + } + + public override void Hide() + { + localCursorContainer.Expire(); + base.Hide(); + } + + protected override bool OnHover(HoverEvent e) => true; + + public class OsuClickToResumeCursor : OsuCursor, IKeyBindingHandler + { + public override bool HandlePositionalInput => true; + + public Action ResumeRequested; + + public OsuClickToResumeCursor() + { + RelativePositionAxes = Axes.Both; + } + + protected override bool OnHover(HoverEvent e) + { + updateColour(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateColour(); + base.OnHoverLost(e); + } + + public bool OnPressed(OsuAction action) + { + switch (action) + { + case OsuAction.LeftButton: + case OsuAction.RightButton: + if (!IsHovered) return false; + + this.ScaleTo(new Vector2(2), TRANSITION_TIME, Easing.OutQuint); + + ResumeRequested?.Invoke(); + return true; + } + + return false; + } + + public bool OnReleased(OsuAction action) => false; + + public void ShowAt(Vector2 activeCursorPosition) => Schedule(() => + { + updateColour(); + this.MoveTo(activeCursorPosition); + this.ScaleTo(new Vector2(4)).Then().ScaleTo(Vector2.One, 1000, Easing.OutQuint); + }); + + private void updateColour() + { + this.FadeColour(IsHovered ? Color4.White : Color4.Orange, 400, Easing.OutQuint); + } + } + } +} diff --git a/osu.Game/Screens/Play/ResumeOverlay.cs b/osu.Game/Screens/Play/ResumeOverlay.cs new file mode 100644 index 0000000000..2ef76069c2 --- /dev/null +++ b/osu.Game/Screens/Play/ResumeOverlay.cs @@ -0,0 +1,74 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Play +{ + /// + /// An overlay which can be used to require further user actions before gameplay is resumed. + /// + public abstract class ResumeOverlay : OverlayContainer + { + public CursorContainer GameplayCursor { get; set; } + + /// + /// The action to be performed to complete resuming. + /// + public Action ResumeAction { private get; set; } + + public virtual CursorContainer LocalCursor => null; + + protected const float TRANSITION_TIME = 500; + + protected override bool BlockPositionalInput => false; + + protected abstract string Message { get; } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + + protected ResumeOverlay() + { + RelativeSizeAxes = Axes.Both; + } + + protected void Resume() + { + ResumeAction?.Invoke(); + Hide(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AddRange(new Drawable[] + { + new OsuSpriteText + { + RelativePositionAxes = Axes.Both, + Y = 0.4f, + Text = Message, + Font = OsuFont.GetFont(size: 30), + Spacing = new Vector2(5, 0), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Colour = colours.Yellow, + Shadow = true, + ShadowColour = new Color4(0, 0, 0, 0.25f) + } + }); + } + + protected override void PopIn() => this.FadeIn(TRANSITION_TIME, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(TRANSITION_TIME, Easing.OutQuint); + } +} From a694626cc66780e6527c3d843b5789d197f8c0b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Mar 2019 16:57:40 +0900 Subject: [PATCH 041/278] Add proper resume request logic --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 31c0afd743..ab10c48ce0 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -169,7 +169,20 @@ namespace osu.Game.Rulesets.UI mod.ApplyToDrawableHitObjects(Playfield.HitObjectContainer.Objects); } - public override void RequestResume(Action continueResume) => continueResume(); + public override void RequestResume(Action continueResume) + { + if (ResumeOverlay != null && (Cursor == null || Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) + { + ResumeOverlay.ResumeAction = continueResume; + ResumeOverlay.Show(); + } + else + continueResume(); + } + + public ResumeOverlay ResumeOverlay { get; private set; } + + protected virtual ResumeOverlay CreateResumeOverlay() => null; /// /// Creates and adds the visual representation of a to this . From 57b3b7b54b8ed092b02f770aaf99f9a2c79c4a8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Mar 2019 11:55:05 +0900 Subject: [PATCH 042/278] Add back resume overlay --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index ab10c48ce0..4c0bc9867b 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -138,7 +138,8 @@ namespace osu.Game.Rulesets.UI { KeyBindingInputManager.AddRange(new Drawable[] { - Playfield + Playfield, + (ResumeOverlay = CreateResumeOverlay()) ?? new Container() }); InternalChildren = new Drawable[] From 650a5c993a176022c410d5f35cd1c60923f9d170 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 15:30:51 +0900 Subject: [PATCH 043/278] Add test --- .../TestCaseResumeOverlay.cs | 70 +++++++++++++++++++ osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 3 +- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/TestCaseResumeOverlay.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseResumeOverlay.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseResumeOverlay.cs new file mode 100644 index 0000000000..5956f12146 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseResumeOverlay.cs @@ -0,0 +1,70 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class TestCaseResumeOverlay : ManualInputManagerTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OsuResumeOverlay), + }; + + public TestCaseResumeOverlay() + { + ManualOsuInputManager osuInputManager; + CursorContainer cursor; + ResumeOverlay resume; + + bool resumeFired = false; + + Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo) + { + Children = new Drawable[] + { + cursor = new CursorContainer(), + resume = new OsuResumeOverlay + { + GameplayCursor = cursor + }, + } + }; + + resume.ResumeAction = () => resumeFired = true; + + AddStep("move mouse to center", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre)); + AddStep("show", () => resume.Show()); + + AddStep("move mouse away", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.TopLeft)); + AddStep("click", () => osuInputManager.GameClick()); + AddAssert("not dismissed", () => !resumeFired && resume.State == Visibility.Visible); + + AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre)); + AddStep("click", () => osuInputManager.GameClick()); + AddAssert("dismissed", () => resumeFired && resume.State == Visibility.Hidden); + } + + private class ManualOsuInputManager : OsuInputManager + { + public ManualOsuInputManager(RulesetInfo ruleset) + : base(ruleset) + { + } + + public void GameClick() + { + KeyBindingContainer.TriggerPressed(OsuAction.LeftButton); + KeyBindingContainer.TriggerReleased(OsuAction.LeftButton); + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index c2000131db..9829839841 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Screens.Play; using osuTK; @@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override string Message => "Click the orange cursor to resume"; [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { Add(clickToResumeCursor = new OsuClickToResumeCursor { ResumeRequested = Resume }); } From 38e481686f03c50c50c958a5c9b71175f4e44218 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 19:21:01 +0900 Subject: [PATCH 044/278] Make PlayfieldAdjustmentContainer universal --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 34 +-- ...s => CatchPlayfieldAdjustmentContainer.cs} | 10 +- .../UI/DrawableCatchRuleset.cs | 2 + .../UI/DrawableManiaRuleset.cs | 9 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 - .../UI/ManiaPlayfieldAdjustmentContainer.cs | 20 ++ .../Edit/OsuHitObjectComposer.cs | 2 +- .../UI/DrawableOsuRuleset.cs | 5 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 45 ++- ....cs => OsuPlayfieldAdjustmentContainer.cs} | 10 +- .../UI/DrawableTaikoRuleset.cs | 2 + osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 256 +++++++++--------- ...s => TaikoPlayfieldAdjustmentContainer.cs} | 11 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 15 +- .../UI/PlayfieldAdjustmentContainer.cs | 19 ++ 15 files changed, 236 insertions(+), 206 deletions(-) rename osu.Game.Rulesets.Catch/UI/{PlayfieldAdjustmentContainer.cs => CatchPlayfieldAdjustmentContainer.cs} (78%) create mode 100644 osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs rename osu.Game.Rulesets.Osu/UI/{PlayfieldAdjustmentContainer.cs => OsuPlayfieldAdjustmentContainer.cs} (82%) rename osu.Game.Rulesets.Taiko/UI/{PlayfieldAdjustmentContainer.cs => TaikoPlayfieldAdjustmentContainer.cs} (68%) create mode 100644 osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4dae95b53c..43d0dc026d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; -using osuTK; namespace osu.Game.Rulesets.Catch.UI { @@ -24,29 +23,20 @@ namespace osu.Game.Rulesets.Catch.UI { Container explodingFruitContainer; - Anchor = Anchor.TopCentre; - Origin = Anchor.TopCentre; - - Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate - - InternalChild = new PlayfieldAdjustmentContainer + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + explodingFruitContainer = new Container { - explodingFruitContainer = new Container - { - RelativeSizeAxes = Axes.Both, - }, - CatcherArea = new CatcherArea(difficulty) - { - GetVisualRepresentation = getVisualRepresentation, - ExplodingFruitTarget = explodingFruitContainer, - Anchor = Anchor.BottomLeft, - Origin = Anchor.TopLeft, - }, - HitObjectContainer - } + RelativeSizeAxes = Axes.Both, + }, + CatcherArea = new CatcherArea(difficulty) + { + GetVisualRepresentation = getVisualRepresentation, + ExplodingFruitTarget = explodingFruitContainer, + Anchor = Anchor.BottomLeft, + Origin = Anchor.TopLeft, + }, + HitObjectContainer }; } diff --git a/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs similarity index 78% rename from osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs rename to osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index 76daee2bbf..b8d3dc9017 100644 --- a/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -3,17 +3,23 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Rulesets.Catch.UI { - public class PlayfieldAdjustmentContainer : Container + public class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { protected override Container Content => content; private readonly Container content; - public PlayfieldAdjustmentContainer() + public CatchPlayfieldAdjustmentContainer() { + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + + Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate + InternalChild = new Container { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index 406dc10eea..6981c98ec7 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -36,6 +36,8 @@ namespace osu.Game.Rulesets.Catch.UI protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation); + protected override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new CatchPlayfieldAdjustmentContainer(); + protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); public override DrawableHitObject GetVisualRepresentation(CatchHitObject h) diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index a019401d5b..0dc081f3da 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Beatmaps; @@ -89,11 +88,9 @@ namespace osu.Game.Rulesets.Mania.UI /// The column which intersects with . public Column GetColumnByPosition(Vector2 screenSpacePosition) => Playfield.GetColumnByPosition(screenSpacePosition); - protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }; + protected override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new ManiaPlayfieldAdjustmentContainer(); + + protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages); public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 81888d2773..cbabfcc8b4 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -28,8 +28,6 @@ namespace osu.Game.Rulesets.Mania.UI if (stageDefinitions.Count <= 0) throw new ArgumentException("Can't have zero or fewer stages."); - Size = new Vector2(1, 0.8f); - GridContainer playfieldGrid; AddInternal(playfieldGrid = new GridContainer { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs new file mode 100644 index 0000000000..d893a3fdde --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Rulesets.UI; +using osuTK; + +namespace osu.Game.Rulesets.Mania.UI +{ + public class ManiaPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + { + public ManiaPlayfieldAdjustmentContainer() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Size = new Vector2(1, 0.8f); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index dd3925e04f..952fe0b708 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Edit public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler(); - protected override Container CreateLayerContainer() => new PlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both }; + protected override Container CreateLayerContainer() => new OsuPlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both }; public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) { diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index b632e0fb05..1c5032a938 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -1,7 +1,8 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; @@ -32,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.UI protected override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); + protected override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer(); + public override DrawableHitObject GetVisualRepresentation(OsuHitObject h) { switch (h) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 51733c3c01..5e532d9b04 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -24,41 +24,28 @@ namespace osu.Game.Rulesets.Osu.UI public static readonly Vector2 BASE_SIZE = new Vector2(512, 384); - private readonly PlayfieldAdjustmentContainer adjustmentContainer; - - protected override Container CursorTargetContainer => adjustmentContainer; - protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); public OsuPlayfield() { - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - - Size = new Vector2(0.75f); - - InternalChild = adjustmentContainer = new PlayfieldAdjustmentContainer + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + connectionLayer = new FollowPointRenderer { - connectionLayer = new FollowPointRenderer - { - RelativeSizeAxes = Axes.Both, - Depth = 2, - }, - judgementLayer = new JudgementContainer - { - RelativeSizeAxes = Axes.Both, - Depth = 1, - }, - HitObjectContainer, - approachCircles = new ApproachCircleProxyContainer - { - RelativeSizeAxes = Axes.Both, - Depth = -1, - }, - } + RelativeSizeAxes = Axes.Both, + Depth = 2, + }, + judgementLayer = new JudgementContainer + { + RelativeSizeAxes = Axes.Both, + Depth = 1, + }, + HitObjectContainer, + approachCircles = new ApproachCircleProxyContainer + { + RelativeSizeAxes = Axes.Both, + Depth = -1, + }, }; } diff --git a/osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs similarity index 82% rename from osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs rename to osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index c383c47491..e28ff5f460 100644 --- a/osu.Game.Rulesets.Osu/UI/PlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -3,17 +3,23 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Rulesets.Osu.UI { - public class PlayfieldAdjustmentContainer : Container + public class OsuPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { protected override Container Content => content; private readonly Container content; - public PlayfieldAdjustmentContainer() + public OsuPlayfieldAdjustmentContainer() { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Size = new Vector2(0.75f); + InternalChild = new Container { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 899b91863e..f595432082 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -81,6 +81,8 @@ namespace osu.Game.Rulesets.Taiko.UI public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this); + protected override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer(); + protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 35b941b52b..dbff5270d2 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -55,143 +55,137 @@ namespace osu.Game.Rulesets.Taiko.UI public TaikoPlayfield(ControlPointInfo controlPoints) { - InternalChild = new PlayfieldAdjustmentContainer + InternalChildren = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + backgroundContainer = new Container { - backgroundContainer = new Container + Name = "Transparent playfield background", + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters { - Name = "Transparent playfield background", - RelativeSizeAxes = Axes.Both, - Masking = true, - EdgeEffect = new EdgeEffectParameters + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.2f), + Radius = 5, + }, + Children = new Drawable[] + { + background = new Box { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.2f), - Radius = 5, + RelativeSizeAxes = Axes.Both, + Alpha = 0.6f }, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.6f - }, - } - }, - new Container - { - Name = "Right area", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = left_area_size }, - Children = new Drawable[] - { - new Container - { - Name = "Masked elements before hit objects", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Masking = true, - Children = new Drawable[] - { - hitExplosionContainer = new Container - { - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit, - Blending = BlendingMode.Additive, - }, - HitTarget = new HitTarget - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit - } - } - }, - barlineContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = HIT_TARGET_OFFSET } - }, - new Container - { - Name = "Hit objects", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Masking = true, - Child = HitObjectContainer - }, - kiaiExplosionContainer = new Container - { - Name = "Kiai hit explosions", - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit, - Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Blending = BlendingMode.Additive - }, - judgementContainer = new JudgementContainer - { - Name = "Judgements", - RelativeSizeAxes = Axes.Y, - Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - Blending = BlendingMode.Additive - }, - } - }, - overlayBackgroundContainer = new Container - { - Name = "Left overlay", - RelativeSizeAxes = Axes.Y, - Size = new Vector2(left_area_size, 1), - Children = new Drawable[] - { - overlayBackground = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new InputDrum(controlPoints) - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Scale = new Vector2(0.9f), - Margin = new MarginPadding { Right = 20 } - }, - new Box - { - Anchor = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Width = 10, - Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)), - }, - } - }, - new Container - { - Name = "Border", - RelativeSizeAxes = Axes.Both, - Masking = true, - MaskingSmoothness = 0, - BorderThickness = 2, - AlwaysPresent = true, - Children = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - } - }, - topLevelHitContainer = new Container - { - Name = "Top level hit objects", - RelativeSizeAxes = Axes.Both, } + }, + new Container + { + Name = "Right area", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = left_area_size }, + Children = new Drawable[] + { + new Container + { + Name = "Masked elements before hit objects", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, + Masking = true, + Children = new Drawable[] + { + hitExplosionContainer = new Container + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Blending = BlendingMode.Additive, + }, + HitTarget = new HitTarget + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit + } + } + }, + barlineContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = HIT_TARGET_OFFSET } + }, + new Container + { + Name = "Hit objects", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, + Masking = true, + Child = HitObjectContainer + }, + kiaiExplosionContainer = new Container + { + Name = "Kiai hit explosions", + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, + Blending = BlendingMode.Additive + }, + judgementContainer = new JudgementContainer + { + Name = "Judgements", + RelativeSizeAxes = Axes.Y, + Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, + Blending = BlendingMode.Additive + }, + } + }, + overlayBackgroundContainer = new Container + { + Name = "Left overlay", + RelativeSizeAxes = Axes.Y, + Size = new Vector2(left_area_size, 1), + Children = new Drawable[] + { + overlayBackground = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new InputDrum(controlPoints) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Scale = new Vector2(0.9f), + Margin = new MarginPadding { Right = 20 } + }, + new Box + { + Anchor = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = 10, + Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)), + }, + } + }, + new Container + { + Name = "Border", + RelativeSizeAxes = Axes.Both, + Masking = true, + MaskingSmoothness = 0, + BorderThickness = 2, + AlwaysPresent = true, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + }, + topLevelHitContainer = new Container + { + Name = "Top level hit objects", + RelativeSizeAxes = Axes.Both, } }; } diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs similarity index 68% rename from osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs rename to osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 0f0ad59fd3..84464b199e 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -1,16 +1,23 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class PlayfieldAdjustmentContainer : Container + public class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768; private const float default_aspect = 16f / 9f; + public TaikoPlayfieldAdjustmentContainer() + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + } + protected override void Update() { base.Update(); diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 4c0bc9867b..0ced3476d0 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; @@ -133,20 +133,19 @@ namespace osu.Game.Rulesets.UI return dependencies; } + protected virtual PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new PlayfieldAdjustmentContainer(); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - KeyBindingInputManager.AddRange(new Drawable[] - { - Playfield, - (ResumeOverlay = CreateResumeOverlay()) ?? new Container() - }); - InternalChildren = new Drawable[] { frameStabilityContainer = new FrameStabilityContainer { - Child = KeyBindingInputManager, + Child = KeyBindingInputManager + .WithChild(CreatePlayfieldAdjustmentContainer() + .WithChild(Playfield) + ) }, Overlays = new Container { RelativeSizeAxes = Axes.Both } }; diff --git a/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs b/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs new file mode 100644 index 0000000000..fff4a450e5 --- /dev/null +++ b/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Rulesets.UI +{ + /// + /// A container which handles sizing of the and any other components that need to match their size. + /// + public class PlayfieldAdjustmentContainer : Container + { + public PlayfieldAdjustmentContainer() + { + RelativeSizeAxes = Axes.Both; + } + } +} From c79d187a896176018dd38d06c18cf7400a33f6d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 19:21:25 +0900 Subject: [PATCH 045/278] Add final osu! resume screen implementation --- osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs | 6 ++++-- osu.Game/Rulesets/UI/DrawableRuleset.cs | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index 1c5032a938..ffb5d3b5d7 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -1,8 +1,7 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; @@ -15,6 +14,7 @@ using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Play; namespace osu.Game.Rulesets.Osu.UI { @@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Osu.UI protected override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer(); + protected override ResumeOverlay CreateResumeOverlay() => new OsuResumeOverlay(); + public override DrawableHitObject GetVisualRepresentation(OsuHitObject h) { switch (h) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 0ced3476d0..0f61b1cb2f 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; @@ -150,6 +150,13 @@ namespace osu.Game.Rulesets.UI Overlays = new Container { RelativeSizeAxes = Axes.Both } }; + if ((ResumeOverlay = CreateResumeOverlay()) != null) + { + AddInternal(CreateInputManager() + .WithChild(CreatePlayfieldAdjustmentContainer() + .WithChild(ResumeOverlay))); + } + applyRulesetMods(mods, config); loadObjects(); @@ -173,6 +180,7 @@ namespace osu.Game.Rulesets.UI { if (ResumeOverlay != null && (Cursor == null || Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) { + ResumeOverlay.GameplayCursor = Cursor; ResumeOverlay.ResumeAction = continueResume; ResumeOverlay.Show(); } From 95889440488e9639b855e85d0c33e56aec63b6eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 19:21:34 +0900 Subject: [PATCH 046/278] Fix multiple cursors appearing --- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index 9829839841..5312711a7d 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -35,12 +35,16 @@ namespace osu.Game.Rulesets.Osu.UI { base.Show(); clickToResumeCursor.ShowAt(GameplayCursor.ActiveCursor.Position); - Add(localCursorContainer = new GameplayCursorContainer()); + + if (localCursorContainer == null) + Add(localCursorContainer = new GameplayCursorContainer()); } public override void Hide() { - localCursorContainer.Expire(); + localCursorContainer?.Expire(); + localCursorContainer = null; + base.Hide(); } From 06d4856e1716a250d26483aa1e67d3799f33f5bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 19:21:47 +0900 Subject: [PATCH 047/278] Remove unnecessary CursorTargetContainer --- osu.Game/Rulesets/UI/Playfield.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 78d14a27e3..53bfa6af48 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); if (Cursor != null) - CursorTargetContainer.Add(Cursor); + AddInternal(Cursor); } /// @@ -99,11 +99,6 @@ namespace osu.Game.Rulesets.UI /// The cursor, or null if a cursor is not rqeuired. protected virtual CursorContainer CreateCursor() => null; - /// - /// The target container to add the cursor after it is created. - /// - protected virtual Container CursorTargetContainer => null; - /// /// Registers a as a nested . /// This does not add the to the draw hierarchy. From a23dfb58ad11d7b324aa9301ddc1527c862ce56d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 20:25:16 +0900 Subject: [PATCH 048/278] Add base cursor class to retrieve true visibility state --- .../TestCaseGameplayCursor.cs | 3 ++- .../Edit/DrawableOsuEditRuleset.cs | 3 +-- .../UI/Cursor/GameplayCursorContainer.cs | 6 ++--- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 +-- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 3 ++- osu.Game/Rulesets/UI/DrawableRuleset.cs | 8 +++--- .../Rulesets/UI/GameplayCursorContainer.cs | 25 +++++++++++++++++++ osu.Game/Rulesets/UI/Playfield.cs | 5 ++-- 8 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 osu.Game/Rulesets/UI/GameplayCursorContainer.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs index 5c1e775c01..1e2a936002 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Cursor; using osu.Game.Rulesets.Osu.UI.Cursor; +using osu.Game.Rulesets.UI; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests @@ -27,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Tests [BackgroundDependencyLoader] private void load() { - Add(cursorContainer = new GameplayCursorContainer { RelativeSizeAxes = Axes.Both }); + Add(cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }); } } } diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index 1a6e78d918..3ae554a5d7 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; @@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Edit private class OsuPlayfieldNoCursor : OsuPlayfield { - protected override CursorContainer CreateCursor() => null; + protected override GameplayCursorContainer CreateCursor() => null; } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs index b64561e4f7..f028a5f15c 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs @@ -3,12 +3,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class GameplayCursorContainer : CursorContainer, IKeyBindingHandler + public class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler { protected override Drawable CreateCursor() => new OsuCursor(); @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly Container fadeContainer; - public GameplayCursorContainer() + public OsuCursorContainer() { InternalChild = fadeContainer = new Container { diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 5e532d9b04..0cbe0cca85 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; -using osu.Framework.Graphics.Cursor; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.UI.Cursor; @@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.UI public static readonly Vector2 BASE_SIZE = new Vector2(512, 384); - protected override CursorContainer CreateCursor() => new GameplayCursorContainer(); + protected override GameplayCursorContainer CreateCursor() => new OsuCursorContainer(); public OsuPlayfield() { diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index 5312711a7d..0d4e7edb7b 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.UI.Cursor; +using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; using osuTK; using osuTK.Graphics; @@ -37,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.UI clickToResumeCursor.ShowAt(GameplayCursor.ActiveCursor.Position); if (localCursorContainer == null) - Add(localCursorContainer = new GameplayCursorContainer()); + Add(localCursorContainer = new OsuCursorContainer()); } public override void Hide() diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 0f61b1cb2f..2b64aec8ea 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -178,7 +178,7 @@ namespace osu.Game.Rulesets.UI public override void RequestResume(Action continueResume) { - if (ResumeOverlay != null && (Cursor == null || Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) + if (ResumeOverlay != null && (Cursor == null || ((GameplayCursorContainer)Cursor).LastFrameState == Visibility.Visible && Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) { ResumeOverlay.GameplayCursor = Cursor; ResumeOverlay.ResumeAction = continueResume; @@ -284,7 +284,9 @@ namespace osu.Game.Rulesets.UI protected override bool OnHover(HoverEvent e) => true; // required for IProvideCursor - public override CursorContainer Cursor => Playfield.Cursor; + CursorContainer IProvideCursor.Cursor => Playfield.Cursor; + + public override GameplayCursorContainer Cursor => Playfield.Cursor; public bool ProvidingUserCursor => Playfield.Cursor != null && !HasReplayLoaded.Value; @@ -354,7 +356,7 @@ namespace osu.Game.Rulesets.UI /// /// The cursor being displayed by the . May be null if no cursor is provided. /// - public abstract CursorContainer Cursor { get; } + public abstract GameplayCursorContainer Cursor { get; } /// /// Sets a replay to be used, overriding local input. diff --git a/osu.Game/Rulesets/UI/GameplayCursorContainer.cs b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs new file mode 100644 index 0000000000..de73c08809 --- /dev/null +++ b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; + +namespace osu.Game.Rulesets.UI +{ + public class GameplayCursorContainer : CursorContainer + { + /// + /// Because Show/Hide are executed by a parent, is updated immediately even if the cursor + /// is in a non-updating state (via limitations). + /// + /// This holds the true visibility value. + /// + public Visibility LastFrameState; + + protected override void Update() + { + base.Update(); + LastFrameState = State; + } + } +} diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 53bfa6af48..48b950c070 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osuTK; @@ -90,14 +89,14 @@ namespace osu.Game.Rulesets.UI /// /// The cursor currently being used by this . May be null if no cursor is provided. /// - public CursorContainer Cursor { get; private set; } + public GameplayCursorContainer Cursor { get; private set; } /// /// Provide an optional cursor which is to be used for gameplay. /// If providing a cursor, must also point to a valid target container. /// /// The cursor, or null if a cursor is not rqeuired. - protected virtual CursorContainer CreateCursor() => null; + protected virtual GameplayCursorContainer CreateCursor() => null; /// /// Registers a as a nested . From 245f463e3fd554f522f666a01c4864ccfbbde7cd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 20:25:47 +0900 Subject: [PATCH 049/278] Don't update gameplay loop while paused --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 5 ++++- osu.Game/Screens/Play/GameplayClock.cs | 3 +++ osu.Game/Screens/Play/GameplayClockContainer.cs | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 161e7aecb4..deec2b8eac 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -36,7 +36,10 @@ namespace osu.Game.Rulesets.UI private void load(GameplayClock clock) { if (clock != null) + { parentGameplayClock = clock; + gameplayClock.IsPaused.BindTo(clock.IsPaused); + } } protected override void LoadComplete() @@ -68,7 +71,7 @@ namespace osu.Game.Rulesets.UI public override bool UpdateSubTree() { requireMoreUpdateLoops = true; - validState = true; + validState = !gameplayClock.IsPaused.Value; int loops = 0; diff --git a/osu.Game/Screens/Play/GameplayClock.cs b/osu.Game/Screens/Play/GameplayClock.cs index 0400bfbc27..3efcfa0f65 100644 --- a/osu.Game/Screens/Play/GameplayClock.cs +++ b/osu.Game/Screens/Play/GameplayClock.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Bindables; using osu.Framework.Timing; namespace osu.Game.Screens.Play @@ -17,6 +18,8 @@ namespace osu.Game.Screens.Play { private readonly IFrameBasedClock underlyingClock; + public readonly BindableBool IsPaused = new BindableBool(); + public GameplayClock(IFrameBasedClock underlyingClock) { this.underlyingClock = underlyingClock; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index deac5e02bf..546364b26d 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -79,6 +79,8 @@ namespace osu.Game.Screens.Play // the clock to be exposed via DI to children. GameplayClock = new GameplayClock(offsetClock); + + GameplayClock.IsPaused.BindTo(IsPaused); } [BackgroundDependencyLoader] From 15aea7f745ac0b9dfa4695eef7da897f84a02418 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 21:39:15 +0900 Subject: [PATCH 050/278] Update framework --- osu.Game/Screens/Multi/MultiplayerSubScreen.cs | 2 -- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs index ad72072981..65e501b114 100644 --- a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs @@ -14,8 +14,6 @@ namespace osu.Game.Screens.Multi { public override bool DisallowExternalBeatmapRulesetChanges => false; - public override bool RemoveWhenNotAlive => false; - public virtual string ShortTitle => Title; [Resolved(CanBeNull = true)] diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 71324ea0f0..eb5d0fd8ee 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 02099a59bb..c3792a48a1 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From a642f1013167c61cd60fe4f76f69c4b391600f02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 21:52:01 +0900 Subject: [PATCH 051/278] Remove redundant cast --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 2b64aec8ea..bdb1c9c0cc 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -178,7 +178,7 @@ namespace osu.Game.Rulesets.UI public override void RequestResume(Action continueResume) { - if (ResumeOverlay != null && (Cursor == null || ((GameplayCursorContainer)Cursor).LastFrameState == Visibility.Visible && Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) + if (ResumeOverlay != null && (Cursor == null || Cursor.LastFrameState == Visibility.Visible && Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) { ResumeOverlay.GameplayCursor = Cursor; ResumeOverlay.ResumeAction = continueResume; From 82140c38fc39ca7e0124b80ebdd043fd72281584 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Mar 2019 22:00:33 +0900 Subject: [PATCH 052/278] Apply CI fixes --- .../{GameplayCursorContainer.cs => OsuCursorContainer.cs} | 0 osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Rulesets.Osu/UI/Cursor/{GameplayCursorContainer.cs => OsuCursorContainer.cs} (100%) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs similarity index 100% rename from osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursorContainer.cs rename to osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index bdb1c9c0cc..905da3c33b 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -178,7 +178,7 @@ namespace osu.Game.Rulesets.UI public override void RequestResume(Action continueResume) { - if (ResumeOverlay != null && (Cursor == null || Cursor.LastFrameState == Visibility.Visible && Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))) + if (ResumeOverlay != null && (Cursor == null || (Cursor.LastFrameState == Visibility.Visible && Contains(Cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre)))) { ResumeOverlay.GameplayCursor = Cursor; ResumeOverlay.ResumeAction = continueResume; From f4aeb390efb7ee2a8620a73c02e0a43bf25b1f86 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Mar 2019 10:21:34 +0900 Subject: [PATCH 053/278] Initial re-layout of score table --- .../TestCaseBeatmapScoresContainer.cs | 12 +- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 213 +++++++++++++++++- 2 files changed, 222 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs index b626c23f25..2bc0796045 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs @@ -1,18 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; @@ -24,6 +23,15 @@ namespace osu.Game.Tests.Visual.SongSelect [Description("in BeatmapOverlay")] public class TestCaseBeatmapScoresContainer : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ScoresContainer), + typeof(ScoreTable), + typeof(ScoreTableRow), + typeof(ScoreTableHeader), + typeof(ScoreTableScore) + }; + private readonly Box background; public TestCaseBeatmapScoresContainer() diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index aacbc12cd8..7e838f0aae 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -6,19 +6,52 @@ using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; using System.Linq; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { public class ScoreTable : CompositeDrawable { + private const int fade_duration = 100; + private const int text_size = 14; + private readonly FillFlowContainer scoresFlow; + private readonly ScoresGrid scoresGrid; public ScoreTable() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = scoresFlow = new FillFlowContainer + InternalChild = scoresGrid = new ScoresGrid + { + RelativeSizeAxes = Axes.X, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, 40), + new Dimension(GridSizeMode.Absolute, 70), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed, minSize: 180), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70), + new Dimension(GridSizeMode.AutoSize), + } + }; + + scoresFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -48,6 +81,184 @@ namespace osu.Game.Overlays.BeatmapSet.Scores int index = 0; foreach (var s in value) scoresFlow.Add(new ScoreTableScore(index++, s, maxModsAmount)); + + scoresGrid.Content = value.Select((s, i) => createRowContents(s, i).ToArray()).ToArray(); + } + } + + private IEnumerable createRowContents(APIScoreInfo score, int index) + { + yield return new SpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Text = $"#{index + 1}", + Font = @"Exo2.0-Bold", + TextSize = text_size, + }; + + yield return new DrawableRank(score.Rank) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(30, 20), + FillMode = FillMode.Fit, + }; + + yield return new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Right = 20 }, + Text = $@"{score.TotalScore:N0}", + TextSize = text_size, + Font = index == 0 ? OsuFont.GetFont(weight: FontWeight.Bold) : OsuFont.Default + }; + + yield return new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Right = 20 }, + Text = $@"{score.Accuracy:P2}", + TextSize = text_size, + Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White + }; + + yield return new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new DrawableFlag(score.User.Country) + { + Size = new Vector2(20, 13), + }, + new ClickableScoreUsername + { + User = score.User, + } + } + }; + + yield return new SpriteText + { + Text = $@"{score.MaxCombo:N0}x", + TextSize = text_size, + }; + + yield return new SpriteText + { + Text = $"{score.Statistics[HitResult.Great]}", + TextSize = text_size, + Colour = score.Statistics[HitResult.Great] == 0 ? Color4.Gray : Color4.White + }; + + yield return new SpriteText + { + Text = $"{score.Statistics[HitResult.Good]}", + TextSize = text_size, + Colour = score.Statistics[HitResult.Good] == 0 ? Color4.Gray : Color4.White + }; + + yield return new SpriteText + { + Text = $"{score.Statistics[HitResult.Meh]}", + TextSize = text_size, + Colour = score.Statistics[HitResult.Meh] == 0 ? Color4.Gray : Color4.White + }; + + yield return new SpriteText + { + Text = $"{score.Statistics[HitResult.Miss]}", + TextSize = text_size, + Colour = score.Statistics[HitResult.Miss] == 0 ? Color4.Gray : Color4.White + }; + + yield return new SpriteText + { + Text = $@"{score.PP:N0}", + TextSize = text_size, + }; + + yield return new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f), + }) + }; + } + + private class ScoresGrid : GridContainer + { + public ScoresGrid() + { + AutoSizeAxes = Axes.Y; + } + + public Drawable[][] Content + { + get => base.Content; + set + { + base.Content = value; + + RowDimensions = Enumerable.Repeat(new Dimension(GridSizeMode.Absolute, 25), value.Length).ToArray(); + } + } + } + + private class ClickableScoreUsername : ClickableUserContainer + { + private readonly SpriteText text; + private readonly SpriteText textBold; + + public ClickableScoreUsername() + { + Add(text = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + }); + + Add(textBold = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Font = @"Exo2.0-Bold", + Alpha = 0, + }); + } + + protected override void OnUserChange(User user) + { + text.Text = textBold.Text = user.Username; + } + + protected override bool OnHover(HoverEvent e) + { + textBold.FadeIn(fade_duration, Easing.OutQuint); + text.FadeOut(fade_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + textBold.FadeOut(fade_duration, Easing.OutQuint); + text.FadeIn(fade_duration, Easing.OutQuint); + base.OnHoverLost(e); } } } From a0f6718145f4cadb74e86161fe635c221d30e2d9 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 26 Mar 2019 10:48:29 +0900 Subject: [PATCH 054/278] Better tests and implementation --- .../Visual/TestCaseFacadeContainer.cs | 75 ++++++++++++++++++- .../Graphics/Containers/FacadeContainer.cs | 55 ++++++++------ osu.Game/Screens/Play/PlayerLoader.cs | 5 +- 3 files changed, 109 insertions(+), 26 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs index 3063a4ca3f..d3f854998c 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -9,7 +9,9 @@ using NUnit.Framework; 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.Testing; using osu.Game.Configuration; using osu.Game.Graphics.Containers; @@ -18,6 +20,7 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; +using osuTK; using osuTK.Graphics; namespace osu.Game.Tests.Visual @@ -36,6 +39,7 @@ namespace osu.Game.Tests.Visual private readonly Bindable uiScale = new Bindable(); + private TestScreen screen1; private OsuScreen baseScreen; public TestCaseFacadeContainer() @@ -49,7 +53,6 @@ namespace osu.Game.Tests.Visual baseScreen = null; config.BindWith(OsuSetting.UIScale, uiScale); AddSliderStep("Adjust scale", 1f, 1.5f, 1f, v => uiScale.Value = v); - AddToggleStep("Toggle mods", b => { Beatmap.Value.Mods.Value = b ? Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }) : Enumerable.Empty(); }); } [SetUpSteps] @@ -58,9 +61,18 @@ namespace osu.Game.Tests.Visual AddStep("Null screens", () => baseScreen = null); } + [Test] + public void IsolatedTest() + { + bool randomPositions = false; + AddToggleStep("Toggle move continuously", b => randomPositions = b); + AddStep("Move facade to random position", () => LoadScreen(screen1 = new TestScreen(randomPositions))); + } + [Test] public void PlayerLoaderTest() { + AddToggleStep("Toggle mods", b => { Beatmap.Value.Mods.Value = b ? Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }) : Enumerable.Empty(); }); AddStep("Add new playerloader", () => LoadScreen(baseScreen = new TestPlayerLoader(() => new TestPlayer { AllowPause = false, @@ -89,6 +101,67 @@ namespace osu.Game.Tests.Visual }; } + private class TestScreen : OsuScreen + { + private TestFacadeContainer facadeContainer; + private FacadeFlowComponent facadeFlowComponent; + private OsuLogo logo; + + private readonly bool randomPositions; + + public TestScreen(bool randomPositions = false) + { + this.randomPositions = randomPositions; + } + + private SpriteText positionText; + private SpriteText sizeAxesText; + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = facadeContainer = new TestFacadeContainer + { + Child = facadeFlowComponent = new FacadeFlowComponent + { + AutoSizeAxes = Axes.Both + } + }; + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + base.LogoArriving(logo, resuming); + logo.FadeIn(350); + logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); + facadeContainer.SetLogo(logo); + moveLogoFacade(); + } + + private void moveLogoFacade() + { + Random random = new Random(); + if (facadeFlowComponent.Transforms.Count == 0) + { + facadeFlowComponent.Delay(500).MoveTo(new Vector2(random.Next(0, 800), random.Next(0, 600)), 300); + } + + if (randomPositions) + Schedule(moveLogoFacade); + } + } + + private class FacadeFlowComponent : FillFlowContainer + { + [BackgroundDependencyLoader] + private void load(Facade facade) + { + facade.Anchor = Anchor.TopCentre; + facade.Origin = Anchor.TopCentre; + Child = facade; + } + } + private class TestPlayerLoader : PlayerLoader { public TestPlayerLoader(Func player) diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index d7fae8887f..0511c87166 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -1,10 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.MathUtils; using osu.Game.Screens.Menu; using osuTK; @@ -18,7 +18,6 @@ namespace osu.Game.Graphics.Containers private OsuLogo logo; private bool tracking; - private bool smoothTransform; protected virtual Facade CreateFacade() => new Facade(); @@ -29,7 +28,7 @@ namespace osu.Game.Graphics.Containers private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); - public void SetLogo(OsuLogo logo, bool resuming, double transformDelay) + public void SetLogo(OsuLogo logo, double transformDelay = 0) { if (logo != null) { @@ -38,41 +37,53 @@ namespace osu.Game.Graphics.Containers Scheduler.AddDelayed(() => { tracking = true; - smoothTransform = !resuming; }, transformDelay); } } + private double startTime; + private double duration = 1000; + + private Vector2 startPosition; + private Easing easing = Easing.InOutExpo; + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); - if (logo == null) + if (logo == null || !tracking) return; facade.Size = new Vector2(logo.SizeForFlow * 0.3f); - if (smoothTransform && facade.IsLoaded && logo.Transforms.Count == 0) + if (facade.IsLoaded && logo.Position != logoTrackingPosition) { - // Our initial movement to the tracking location should be smooth. - Schedule(() => + if (logo.RelativePositionAxes != Axes.None) { - facade.Size = new Vector2(logo.SizeForFlow * 0.3f); + logo.Position = logo.Parent.ToLocalSpace(logo.Position); logo.RelativePositionAxes = Axes.None; - logo.MoveTo(logoTrackingPosition, 500, Easing.InOutExpo); - smoothTransform = false; - }); - } - else if (facade.IsLoaded && logo.Transforms.Count == 0) - { - // If all transforms have finished playing, the logo constantly track the position of the facade. - logo.RelativePositionAxes = Axes.None; - logo.Position = logoTrackingPosition; + } + + if (startTime == 0) + { + startTime = Time.Current; + } + + var endTime = startTime + duration; + var remainingDuration = endTime - Time.Current; + + if (remainingDuration <= 0) + { + remainingDuration = 0; + } + + float currentTime = (float)Interpolation.ApplyEasing(easing, remainingDuration / duration); + logo.Position = Vector2.Lerp(logoTrackingPosition, startPosition, currentTime); } } } - - public class Facade : Container - { - } } + +public class Facade : Container +{ +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5817e11277..b7155f771f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -155,7 +155,7 @@ namespace osu.Game.Screens.Play logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); - content.SetLogo(logo, resuming, duration); + content.SetLogo(logo, duration); } protected override void LoadComplete() @@ -167,7 +167,7 @@ namespace osu.Game.Screens.Play private ScheduledDelegate pushDebounce; protected VisualSettings VisualSettings; - // Hhere because IsHovered will not update unless we do so. + // Here because IsHovered will not update unless we do so. public override bool HandlePositionalInput => true; private bool readyForPush => player.LoadState == LoadState.Ready && IsHovered && GetContainingInputManager()?.DraggedDrawable == null; @@ -306,7 +306,6 @@ namespace osu.Game.Screens.Play private Sprite backgroundSprite; private ModDisplay modDisplay; private FillFlowContainer fillFlowContainer; - private FacadeContainer facadeContainer; public bool Loading { From be9ac39f542eb6bea400086c9cf04cb7b4a15e69 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 26 Mar 2019 11:11:27 +0900 Subject: [PATCH 055/278] Cleanup --- .../Visual/TestCaseFacadeContainer.cs | 23 ++++--------------- .../Graphics/Containers/FacadeContainer.cs | 2 +- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs index d3f854998c..5591bec0b8 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -11,7 +11,6 @@ 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.Testing; using osu.Game.Configuration; using osu.Game.Graphics.Containers; @@ -32,6 +31,7 @@ namespace osu.Game.Tests.Visual typeof(PlayerLoader), typeof(Player), typeof(Facade), + typeof(FacadeContainer) }; [Cached] @@ -39,9 +39,6 @@ namespace osu.Game.Tests.Visual private readonly Bindable uiScale = new Bindable(); - private TestScreen screen1; - private OsuScreen baseScreen; - public TestCaseFacadeContainer() { Add(logo = new OsuLogo()); @@ -50,30 +47,23 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - baseScreen = null; config.BindWith(OsuSetting.UIScale, uiScale); AddSliderStep("Adjust scale", 1f, 1.5f, 1f, v => uiScale.Value = v); } - [SetUpSteps] - public void SetUpSteps() - { - AddStep("Null screens", () => baseScreen = null); - } - [Test] public void IsolatedTest() { bool randomPositions = false; AddToggleStep("Toggle move continuously", b => randomPositions = b); - AddStep("Move facade to random position", () => LoadScreen(screen1 = new TestScreen(randomPositions))); + AddStep("Move facade to random position", () => LoadScreen(new TestScreen(randomPositions))); } [Test] public void PlayerLoaderTest() { AddToggleStep("Toggle mods", b => { Beatmap.Value.Mods.Value = b ? Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }) : Enumerable.Empty(); }); - AddStep("Add new playerloader", () => LoadScreen(baseScreen = new TestPlayerLoader(() => new TestPlayer + AddStep("Add new playerloader", () => LoadScreen(new TestPlayerLoader(() => new TestPlayer { AllowPause = false, AllowLeadIn = false, @@ -84,7 +74,7 @@ namespace osu.Game.Tests.Visual [Test] public void MainMenuTest() { - AddStep("Add new Main Menu", () => LoadScreen(baseScreen = new MainMenu())); + AddStep("Add new Main Menu", () => LoadScreen(new MainMenu())); } private class TestFacadeContainer : FacadeContainer @@ -105,8 +95,6 @@ namespace osu.Game.Tests.Visual { private TestFacadeContainer facadeContainer; private FacadeFlowComponent facadeFlowComponent; - private OsuLogo logo; - private readonly bool randomPositions; public TestScreen(bool randomPositions = false) @@ -114,9 +102,6 @@ namespace osu.Game.Tests.Visual this.randomPositions = randomPositions; } - private SpriteText positionText; - private SpriteText sizeAxesText; - [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index 0511c87166..611cc94958 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -60,8 +60,8 @@ namespace osu.Game.Graphics.Containers { if (logo.RelativePositionAxes != Axes.None) { - logo.Position = logo.Parent.ToLocalSpace(logo.Position); logo.RelativePositionAxes = Axes.None; + logo.Position = logo.Parent.ToLocalSpace(logo.Position); } if (startTime == 0) From b75ea295dbf97862711515506e1fad7332ca8120 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 11:28:43 +0900 Subject: [PATCH 056/278] Rename KeyCounterCollection -> KeyCounterDisplay Also fix not working --- osu.Game.Tests/Visual/TestCaseKeyCounter.cs | 4 +-- osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- osu.Game/Rulesets/UI/RulesetInputManager.cs | 28 +++++++++++++------ osu.Game/Screens/Play/HUDOverlay.cs | 4 +-- ...nterCollection.cs => KeyCounterDisplay.cs} | 8 +++--- 5 files changed, 28 insertions(+), 18 deletions(-) rename osu.Game/Screens/Play/{KeyCounterCollection.cs => KeyCounterDisplay.cs} (95%) diff --git a/osu.Game.Tests/Visual/TestCaseKeyCounter.cs b/osu.Game.Tests/Visual/TestCaseKeyCounter.cs index 52caffc29f..9360cfd911 100644 --- a/osu.Game.Tests/Visual/TestCaseKeyCounter.cs +++ b/osu.Game.Tests/Visual/TestCaseKeyCounter.cs @@ -20,13 +20,13 @@ namespace osu.Game.Tests.Visual { typeof(KeyCounterKeyboard), typeof(KeyCounterMouse), - typeof(KeyCounterCollection) + typeof(KeyCounterDisplay) }; public TestCaseKeyCounter() { KeyCounterKeyboard rewindTestKeyCounterKeyboard; - KeyCounterCollection kc = new KeyCounterCollection + KeyCounterDisplay kc = new KeyCounterDisplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 905da3c33b..88fdb9a135 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -232,7 +232,7 @@ namespace osu.Game.Rulesets.UI /// The DrawableHitObject. public abstract DrawableHitObject GetVisualRepresentation(TObject h); - public void Attach(KeyCounterCollection keyCounter) => + public void Attach(KeyCounterDisplay keyCounter) => (KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(keyCounter); /// diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index e303166774..150c53274f 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -6,6 +6,7 @@ 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.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; @@ -34,11 +35,19 @@ namespace osu.Game.Rulesets.UI protected readonly KeyBindingContainer KeyBindingContainer; - protected override Container Content => KeyBindingContainer; + protected override Container Content => content; + + private readonly Container content; + + private class Poop : Container + { + } protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) { - InternalChild = KeyBindingContainer = CreateKeyBindingContainer(ruleset, variant, unique); + InternalChild = KeyBindingContainer = + (KeyBindingContainer)CreateKeyBindingContainer(ruleset, variant, unique) + .WithChild(content = new Container { RelativeSizeAxes = Axes.Both }); } [BackgroundDependencyLoader(true)] @@ -115,18 +124,19 @@ namespace osu.Game.Rulesets.UI #region Key Counter Attachment - public void Attach(KeyCounterCollection keyCounter) + public void Attach(KeyCounterDisplay keyCounter) { var receptor = new ActionReceptor(keyCounter); - Add(receptor); - keyCounter.SetReceptor(receptor); + KeyBindingContainer.Add(receptor); + + keyCounter.SetReceptor(receptor); keyCounter.AddRange(KeyBindingContainer.DefaultKeyBindings.Select(b => b.GetAction()).Distinct().Select(b => new KeyCounterAction(b))); } - public class ActionReceptor : KeyCounterCollection.Receptor, IKeyBindingHandler + public class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler { - public ActionReceptor(KeyCounterCollection target) + public ActionReceptor(KeyCounterDisplay target) : base(target) { } @@ -159,12 +169,12 @@ namespace osu.Game.Rulesets.UI } /// - /// Supports attaching a . + /// Supports attaching a . /// Keys will be populated automatically and a receptor will be injected inside. /// public interface ICanAttachKeyCounter { - void Attach(KeyCounterCollection keyCounter); + void Attach(KeyCounterDisplay keyCounter); } public class RulesetInputManagerInputState : InputState diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 285e6eab23..a7b7f96e7a 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play { private const int duration = 100; - public readonly KeyCounterCollection KeyCounter; + public readonly KeyCounterDisplay KeyCounter; public readonly RollingCounter ComboCounter; public readonly ScoreCounter ScoreCounter; public readonly RollingCounter AccuracyCounter; @@ -201,7 +201,7 @@ namespace osu.Game.Screens.Play Margin = new MarginPadding { Top = 20 } }; - protected virtual KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection + protected virtual KeyCounterDisplay CreateKeyCounter() => new KeyCounterDisplay { FadeTime = 50, Anchor = Anchor.BottomRight, diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs similarity index 95% rename from osu.Game/Screens/Play/KeyCounterCollection.cs rename to osu.Game/Screens/Play/KeyCounterDisplay.cs index 1b43737731..d5967f5899 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -14,14 +14,14 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class KeyCounterCollection : FillFlowContainer + public class KeyCounterDisplay : FillFlowContainer { private const int duration = 100; public readonly Bindable Visible = new Bindable(true); private readonly Bindable configVisibility = new Bindable(); - public KeyCounterCollection() + public KeyCounterDisplay() { Direction = FillDirection.Horizontal; AutoSizeAxes = Axes.Both; @@ -138,9 +138,9 @@ namespace osu.Game.Screens.Play public class Receptor : Drawable { - protected readonly KeyCounterCollection Target; + protected readonly KeyCounterDisplay Target; - public Receptor(KeyCounterCollection target) + public Receptor(KeyCounterDisplay target) { RelativeSizeAxes = Axes.Both; Depth = float.MinValue; From c403dede20ccddd7186fd315acf4a0e5f1d09f49 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 13:16:46 +0900 Subject: [PATCH 057/278] Add ManualInputManager to screen tests Also sanitises content init order (ctor for content; bdl for other) --- .../Visual/Multiplayer/TestCaseLoungeRoomsContainer.cs | 3 ++- osu.Game.Tests/Visual/Tournament/TestCaseDrawings.cs | 4 +++- osu.Game/Tests/Visual/ManualInputManagerTestCase.cs | 3 +-- osu.Game/Tests/Visual/PlayerTestCase.cs | 5 +++++ osu.Game/Tests/Visual/ScreenTestCase.cs | 8 +++++--- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestCaseLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestCaseLoungeRoomsContainer.cs index 34de61cb5b..497da33a05 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestCaseLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestCaseLoungeRoomsContainer.cs @@ -27,7 +27,8 @@ namespace osu.Game.Tests.Visual.Multiplayer [Cached(Type = typeof(IRoomManager))] private TestRoomManager roomManager = new TestRoomManager(); - public TestCaseLoungeRoomsContainer() + [BackgroundDependencyLoader] + private void load() { RoomsContainer container; diff --git a/osu.Game.Tests/Visual/Tournament/TestCaseDrawings.cs b/osu.Game.Tests/Visual/Tournament/TestCaseDrawings.cs index 9453d0a5b2..53fb60bcb6 100644 --- a/osu.Game.Tests/Visual/Tournament/TestCaseDrawings.cs +++ b/osu.Game.Tests/Visual/Tournament/TestCaseDrawings.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; +using osu.Framework.Allocation; using osu.Game.Screens.Tournament; using osu.Game.Screens.Tournament.Teams; @@ -11,7 +12,8 @@ namespace osu.Game.Tests.Visual.Tournament [Description("for tournament use")] public class TestCaseDrawings : ScreenTestCase { - public TestCaseDrawings() + [BackgroundDependencyLoader] + private void load() { LoadScreen(new Drawings { diff --git a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs index 7c7c5938aa..f14ac833e4 100644 --- a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs +++ b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs @@ -14,8 +14,7 @@ namespace osu.Game.Tests.Visual protected ManualInputManagerTestCase() { - base.Content.Add(InputManager = new ManualInputManager()); - ReturnUserInput(); + base.Content.Add(InputManager = new ManualInputManager { UseParentInput = true }); } /// diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index 50cb839ed9..fb10244b12 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Testing; @@ -23,7 +24,11 @@ namespace osu.Game.Tests.Visual protected PlayerTestCase(Ruleset ruleset) { this.ruleset = ruleset; + } + [BackgroundDependencyLoader] + private void load() + { Add(new Box { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Tests/Visual/ScreenTestCase.cs b/osu.Game/Tests/Visual/ScreenTestCase.cs index eec60d01c5..981f9acb63 100644 --- a/osu.Game/Tests/Visual/ScreenTestCase.cs +++ b/osu.Game/Tests/Visual/ScreenTestCase.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Screens; @@ -9,11 +10,12 @@ namespace osu.Game.Tests.Visual /// /// A test case which can be used to test a screen (that relies on OnEntering being called to execute startup instructions). /// - public abstract class ScreenTestCase : OsuTestCase + public abstract class ScreenTestCase : ManualInputManagerTestCase { - private readonly OsuScreenStack stack; + private OsuScreenStack stack; - protected ScreenTestCase() + [BackgroundDependencyLoader] + private void load() { Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; } From 256a579de02228bb3e243c6c6b350c4907eabb63 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 13:17:00 +0900 Subject: [PATCH 058/278] Allow player to not pause on focus loss --- osu.Game/Screens/Play/Player.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7b1cdd21a6..f2fd7e765f 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -47,6 +47,8 @@ namespace osu.Game.Screens.Play public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; + public bool PauseOnFocusLost { get; set; } = true; + private Bindable mouseWheelDisabled; private readonly Bindable storyboardReplacesBackground = new Bindable(); @@ -372,7 +374,7 @@ namespace osu.Game.Screens.Play base.Update(); // eagerly pause when we lose window focus (if we are locally playing). - if (!Game.IsActive.Value) + if (PauseOnFocusLost && !Game.IsActive.Value) Pause(); } From 85c63f14f2e630c5eadf1b66646bb658cdabdd43 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 13:18:33 +0900 Subject: [PATCH 059/278] Add comprehensive player resume testing --- .../Visual/Gameplay/TestCasePause.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePause.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePause.cs index 1ed61c9fe1..a52e84ed62 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePause.cs @@ -1,13 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Cursor; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; +using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { @@ -15,14 +21,52 @@ namespace osu.Game.Tests.Visual.Gameplay { protected new PausePlayer Player => (PausePlayer)base.Player; + private readonly Container content; + + protected override Container Content => content; + public TestCasePause() : base(new OsuRuleset()) { + base.Content.Add(content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }); } [Test] public void TestPauseResume() { + AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10))); + pauseAndConfirm(); + resumeAndConfirm(); + } + + [Test] + public void TestResumeWithResumeOverlay() + { + AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre)); + AddUntilStep("wait for hitobjects", () => Player.ScoreProcessor.Health.Value < 1); + + pauseAndConfirm(); + resume(); + + confirmClockRunning(false); + confirmPauseOverlayShown(false); + + AddStep("click to resume", () => + { + InputManager.PressButton(MouseButton.Left); + InputManager.ReleaseButton(MouseButton.Left); + }); + + confirmClockRunning(true); + } + + [Test] + public void TestResumeWithResumeOverlaySkipped() + { + AddStep("move cursor to button", () => + InputManager.MoveMouseTo(Player.HUDOverlay.HoldToQuit.Children.OfType().First().ScreenSpaceDrawQuad.Centre)); + AddUntilStep("wait for hitobjects", () => Player.ScoreProcessor.Health.Value < 1); + pauseAndConfirm(); resumeAndConfirm(); } @@ -30,6 +74,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestPauseTooSoon() { + AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10))); + pauseAndConfirm(); resumeAndConfirm(); @@ -144,9 +190,16 @@ namespace osu.Game.Tests.Visual.Gameplay public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; + public new HUDOverlay HUDOverlay => base.HUDOverlay; + public bool FailOverlayVisible => FailOverlay.State == Visibility.Visible; public bool PauseOverlayVisible => PauseOverlay.State == Visibility.Visible; + + public PausePlayer() + { + PauseOnFocusLost = false; + } } } } From 27cb4ce0d1a761b1e9df48f92cdd74802c46d061 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 13:48:35 +0900 Subject: [PATCH 060/278] Remove poop --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 150c53274f..656170f339 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -39,10 +39,6 @@ namespace osu.Game.Rulesets.UI private readonly Container content; - private class Poop : Container - { - } - protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) { InternalChild = KeyBindingContainer = From fb302e7ad8e464ac6dd6950c0972819e213147b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Mar 2019 13:58:07 +0900 Subject: [PATCH 061/278] Remove using --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 656170f339..3ce8f92458 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -6,7 +6,6 @@ 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.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; From 3fe52be77febe7ce3e41cc1762717cdd71b02db6 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 26 Mar 2019 17:18:35 +0900 Subject: [PATCH 062/278] Better tests, add documentation --- .../Visual/Gameplay/TestCasePlayerLoader.cs | 7 +- .../Visual/TestCaseFacadeContainer.cs | 30 ++++--- .../Graphics/Containers/FacadeContainer.cs | 78 ++++++++++++------- osu.Game/Screens/Menu/ButtonSystem.cs | 63 +++++++-------- osu.Game/Screens/Play/PlayerLoader.cs | 37 +++++---- 5 files changed, 121 insertions(+), 94 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index 67dba71d45..be2a21d23d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -7,16 +7,13 @@ using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Screens; -using osu.Game.Screens.Menu; using osu.Game.Screens.Play; -using osuTK; namespace osu.Game.Tests.Visual.Gameplay { public class TestCasePlayerLoader : ManualInputManagerTestCase { private PlayerLoader loader; - private readonly OsuScreenStack stack; public TestCasePlayerLoader() @@ -29,8 +26,6 @@ namespace osu.Game.Tests.Visual.Gameplay { Beatmap.Value = new DummyWorkingBeatmap(game); - AddStep("Reset logo position", () => logo = new OsuLogo { Position = new Vector2(0, 0) }); - AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player { AllowPause = false, @@ -58,6 +53,8 @@ namespace osu.Game.Tests.Visual.Gameplay AllowLeadIn = false, AllowResults = false, })); + + Scheduler.AddDelayed(() => slow.Ready = true, 5000); }); AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen()); diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs index 5591bec0b8..0d4caff97e 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -11,7 +11,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; +using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Mods; @@ -31,7 +31,11 @@ namespace osu.Game.Tests.Visual typeof(PlayerLoader), typeof(Player), typeof(Facade), - typeof(FacadeContainer) + typeof(FacadeContainer), + typeof(ButtonSystem), + typeof(ButtonSystemState), + typeof(Menu), + typeof(MainMenu) }; [Cached] @@ -68,15 +72,10 @@ namespace osu.Game.Tests.Visual AllowPause = false, AllowLeadIn = false, AllowResults = false, + Ready = false }))); } - [Test] - public void MainMenuTest() - { - AddStep("Add new Main Menu", () => LoadScreen(new MainMenu())); - } - private class TestFacadeContainer : FacadeContainer { protected override Facade CreateFacade() => new Facade @@ -119,16 +118,23 @@ namespace osu.Game.Tests.Visual base.LogoArriving(logo, resuming); logo.FadeIn(350); logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); - facadeContainer.SetLogo(logo); + facadeContainer.SetLogo(logo, 0.3f, 1000, Easing.InOutQuint); + facadeContainer.Tracking = true; moveLogoFacade(); } + protected override void LogoExiting(OsuLogo logo) + { + base.LogoExiting(logo); + facadeContainer.Tracking = false; + } + private void moveLogoFacade() { Random random = new Random(); if (facadeFlowComponent.Transforms.Count == 0) { - facadeFlowComponent.Delay(500).MoveTo(new Vector2(random.Next(0, 800), random.Next(0, 600)), 300); + facadeFlowComponent.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); } if (randomPositions) @@ -159,11 +165,13 @@ namespace osu.Game.Tests.Visual private class TestPlayer : Player { + public bool Ready; + [BackgroundDependencyLoader] private void load() { // Never finish loading - while (true) + while (!Ready) Thread.Sleep(1); } } diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index 611cc94958..47ba738f1c 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -10,80 +10,98 @@ using osuTK; namespace osu.Game.Graphics.Containers { + /// + /// A container that creates a to be used by its children. + /// This container also updates the position and size of the Facade, and contains logic for tracking an on the Facade's position. + /// public class FacadeContainer : Container { + protected virtual Facade CreateFacade() => new Facade(); + + public Facade Facade => facade; + + /// + /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. + /// + public bool Tracking; + [Cached] private Facade facade; private OsuLogo logo; + private float facadeScale; - private bool tracking; - - protected virtual Facade CreateFacade() => new Facade(); + private Vector2 startPosition; + private Easing easing; + private double startTime; + private double duration; public FacadeContainer() { facade = CreateFacade(); } - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); - - public void SetLogo(OsuLogo logo, double transformDelay = 0) + /// + /// Set the logo that should track the Facade's position, as well as how it should transform to its initial position. + /// + /// The instance of the logo to be used for tracking. + /// The scale of the facade. + /// The duration of the initial transform. Default is instant. + /// The easing type of the initial transform. + public void SetLogo(OsuLogo logo, float facadeScale, double duration = 0, Easing easing = Easing.None) { if (logo != null) { - facade.Size = new Vector2(logo.SizeForFlow * 0.3f); this.logo = logo; - Scheduler.AddDelayed(() => - { - tracking = true; - }, transformDelay); } + + this.facadeScale = facadeScale; + this.duration = duration; + this.easing = easing; } - private double startTime; - private double duration = 1000; - - private Vector2 startPosition; - private Easing easing = Easing.InOutExpo; + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); - if (logo == null || !tracking) + if (logo == null || !Tracking) return; - facade.Size = new Vector2(logo.SizeForFlow * 0.3f); + facade.Size = new Vector2(logo.SizeForFlow * facadeScale); if (facade.IsLoaded && logo.Position != logoTrackingPosition) { - if (logo.RelativePositionAxes != Axes.None) - { - logo.RelativePositionAxes = Axes.None; - logo.Position = logo.Parent.ToLocalSpace(logo.Position); - } + // Required for the correct position of the logo to be set with respect to logoTrackingPosition + logo.RelativePositionAxes = Axes.None; + // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == 0) { startTime = Time.Current; + startPosition = logo.Position; } var endTime = startTime + duration; var remainingDuration = endTime - Time.Current; - if (remainingDuration <= 0) - { - remainingDuration = 0; - } + // If our transform should be instant, our position should already be at logoTrackingPosition, thus set the blend to 0. + // If we are already past when the transform should be finished playing, set the blend to 0 so that the logo is always at the position of the facade. + var blend = duration > 0 && remainingDuration > 0 + ? (float)Interpolation.ApplyEasing(easing, remainingDuration / duration) + : 0; - float currentTime = (float)Interpolation.ApplyEasing(easing, remainingDuration / duration); - logo.Position = Vector2.Lerp(logoTrackingPosition, startPosition, currentTime); + // Interpolate the position of the logo, where blend 0 is the position of the Facade, and blend 1 is where the logo was when it first began interpolating. + logo.Position = Vector2.Lerp(logoTrackingPosition, startPosition, blend); } } } } +/// +/// A placeholder container that serves as a dummy object to denote another object's location and size. +/// public class Facade : Container { -} \ No newline at end of file +} diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 3df4ef9059..4c0bcd399a 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; @@ -16,6 +17,7 @@ using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Threading; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.Online.API; @@ -53,15 +55,19 @@ namespace osu.Game.Screens.Menu if (this.logo != null) { this.logo.Action = onOsuLogo; + facadeContainer.SetLogo(logo, 0.5f); // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); updateLogoState(); } + else + { + facadeContainer.Tracking = false; + } } - private readonly Drawable iconFacade; private readonly ButtonArea buttonArea; private readonly Button backButton; @@ -71,26 +77,29 @@ namespace osu.Game.Screens.Menu private SampleChannel sampleBack; + private readonly FacadeContainer facadeContainer; + public ButtonSystem() { RelativeSizeAxes = Axes.Both; - Child = buttonArea = new ButtonArea(); + Child = facadeContainer = new FacadeContainer + { + RelativeSizeAxes = Axes.Both, + Child = buttonArea = new ButtonArea() + }; - buttonArea.AddRange(new[] + buttonArea.AddRange(new Container[] { new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), backButton = new Button(@"back", @"button-back-select", FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH) { VisibleState = ButtonSystemState.Play, }, - iconFacade = new Container //need a container to make the osu! icon flow properly. - { - Size = new Vector2(0, ButtonArea.BUTTON_AREA_HEIGHT) - } + facadeContainer.Facade }); - buttonArea.Flow.CentreTarget = iconFacade; + buttonArea.Flow.CentreTarget = facadeContainer.Facade; } [Resolved(CanBeNull = true)] @@ -120,6 +129,15 @@ namespace osu.Game.Screens.Menu buttonArea.AddRange(buttonsPlay); buttonArea.AddRange(buttonsTopLevel); + buttonArea.ForEach(b => + { + if (b is Button) + { + b.Origin = Anchor.CentreLeft; + b.Anchor = Anchor.CentreLeft; + } + }); + isIdle.ValueChanged += idle => updateIdleState(idle.NewValue); if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle); @@ -247,7 +265,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - logoTracking = false; + facadeContainer.Tracking = false; game?.Toolbar.Hide(); @@ -266,19 +284,16 @@ namespace osu.Game.Screens.Menu break; case ButtonSystemState.Initial: logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.None; bool impact = logo.Scale.X > 0.6f; if (lastState == ButtonSystemState.Initial) logo.ScaleTo(0.5f, 200, Easing.In); - logo.MoveTo(logoTrackingPosition, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); - logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - logoTracking = true; + facadeContainer.Tracking = true; if (impact) logo.Impact(); @@ -288,35 +303,17 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.None; - logoTracking = true; + facadeContainer.Tracking = true; logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; } break; case ButtonSystemState.EnteringMode: - logoTracking = true; + facadeContainer.Tracking = true; break; } } - - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(iconFacade.ScreenSpaceDrawQuad.Centre); - - private bool logoTracking; - - protected override void Update() - { - base.Update(); - - if (logo != null) - { - if (logoTracking && logo.RelativePositionAxes == Axes.None && iconFacade.IsLoaded) - logo.Position = logoTrackingPosition; - - iconFacade.Width = logo.SizeForFlow * 0.5f; - } - } } public enum ButtonSystemState diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index b7155f771f..f35eb6979d 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play private Player player; - private FacadeContainer content; + private FacadeContainer facadeContainer; protected virtual FacadeContainer CreateFacadeContainer() => new FacadeContainer(); @@ -62,11 +62,11 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - InternalChild = content = CreateFacadeContainer(); - content.Anchor = Anchor.Centre; - content.Origin = Anchor.Centre; - content.RelativeSizeAxes = Axes.Both; - content.Children = new Drawable[] + InternalChild = facadeContainer = CreateFacadeContainer(); + facadeContainer.Anchor = Anchor.Centre; + facadeContainer.Origin = Anchor.Centre; + facadeContainer.RelativeSizeAxes = Axes.Both; + facadeContainer.Children = new Drawable[] { info = new BeatmapMetadataDisplay(Beatmap.Value) { @@ -122,21 +122,21 @@ namespace osu.Game.Screens.Play private void contentIn() { - content.ScaleTo(1, 650, Easing.OutQuint); - content.FadeInFromZero(400); + facadeContainer.ScaleTo(1, 650, Easing.OutQuint); + facadeContainer.FadeInFromZero(400); } private void contentOut() { - content.ScaleTo(0.7f, 300, Easing.InQuint); - content.FadeOut(250); + facadeContainer.ScaleTo(0.7f, 300, Easing.InQuint); + facadeContainer.FadeOut(250); } public override void OnEntering(IScreen last) { base.OnEntering(last); - content.ScaleTo(0.7f); + facadeContainer.ScaleTo(0.7f); Background?.FadeColour(Color4.White, 800, Easing.OutQuint); contentIn(); @@ -155,7 +155,15 @@ namespace osu.Game.Screens.Play logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); - content.SetLogo(logo, duration); + facadeContainer.SetLogo(logo, 0.3f, 500, Easing.InOutQuint); + + Scheduler.AddDelayed(() => facadeContainer.Tracking = true, duration); + } + + protected override void LogoExiting(OsuLogo logo) + { + base.LogoExiting(logo); + facadeContainer.Tracking = false; } protected override void LoadComplete() @@ -230,7 +238,7 @@ namespace osu.Game.Screens.Play public override bool OnExiting(IScreen next) { - content.ScaleTo(0.7f, 150, Easing.InQuint); + facadeContainer.ScaleTo(0.7f, 150, Easing.InQuint); this.FadeOut(150); cancelLoad(); @@ -305,7 +313,6 @@ namespace osu.Game.Screens.Play private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; - private FillFlowContainer fillFlowContainer; public bool Loading { @@ -340,7 +347,7 @@ namespace osu.Game.Screens.Play AutoSizeAxes = Axes.Both; Children = new Drawable[] { - fillFlowContainer = new FillFlowContainer + new FillFlowContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopCentre, From adab31fd582dfe6509e863f3f221b012271142b1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Mar 2019 17:38:56 +0900 Subject: [PATCH 063/278] Cleanup + fix up score table layout --- .../Online/TestCaseBeatmapSetOverlay.cs | 6 +- .../TestCaseBeatmapScoresContainer.cs | 5 +- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 237 +++-------------- .../BeatmapSet/Scores/ScoreTableHeader.cs | 70 ----- .../BeatmapSet/Scores/ScoreTableHeaderRow.cs | 46 ++++ .../BeatmapSet/Scores/ScoreTableRow.cs | 246 ++++++------------ .../Scores/ScoreTableRowBackground.cs | 64 +++++ .../BeatmapSet/Scores/ScoreTableScore.cs | 220 ---------------- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 168 ++++++++++++ 9 files changed, 401 insertions(+), 661 deletions(-) delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs diff --git a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs index df24c42b00..19d295cf12 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs @@ -25,7 +25,11 @@ namespace osu.Game.Tests.Visual.Online { typeof(Header), typeof(ClickableUserContainer), - typeof(ScoreTableScore), + typeof(ScoreTable), + typeof(ScoreTableRow), + typeof(ScoreTableHeaderRow), + typeof(ScoreTableScoreRow), + typeof(ScoreTableRowBackground), typeof(DrawableTopScore), typeof(ScoresContainer), typeof(AuthorInfo), diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs index 2bc0796045..63dacef8fa 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs @@ -28,8 +28,9 @@ namespace osu.Game.Tests.Visual.SongSelect typeof(ScoresContainer), typeof(ScoreTable), typeof(ScoreTableRow), - typeof(ScoreTableHeader), - typeof(ScoreTableScore) + typeof(ScoreTableHeaderRow), + typeof(ScoreTableScoreRow), + typeof(ScoreTableRowBackground), }; private readonly Box background; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7e838f0aae..e2acf778a3 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -6,203 +6,74 @@ using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System.Collections.Generic; using System.Linq; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; -using osu.Game.Users; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { public class ScoreTable : CompositeDrawable { - private const int fade_duration = 100; - private const int text_size = 14; - - private readonly FillFlowContainer scoresFlow; private readonly ScoresGrid scoresGrid; + private readonly FillFlowContainer backgroundFlow; public ScoreTable() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = scoresGrid = new ScoresGrid + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.X, - ColumnDimensions = new[] + backgroundFlow = new FillFlowContainer { - new Dimension(GridSizeMode.Absolute, 40), - new Dimension(GridSizeMode.Absolute, 70), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed, minSize: 180), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70), - new Dimension(GridSizeMode.AutoSize), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 25 } + }, + scoresGrid = new ScoresGrid + { + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, 40), + new Dimension(GridSizeMode.Absolute, 70), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed, minSize: 150), + new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), + new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70), + new Dimension(GridSizeMode.AutoSize), + } } }; - - scoresFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - }; } public IEnumerable Scores { set { - scoresFlow.Clear(); - if (value == null || !value.Any()) return; - int maxModsAmount = 0; - foreach (var s in value) - { - var scoreModsAmount = s.Mods.Length; - if (scoreModsAmount > maxModsAmount) - maxModsAmount = scoreModsAmount; - } - - scoresFlow.Add(new ScoreTableHeader(maxModsAmount)); + var content = new List { new ScoreTableHeaderRow().CreateDrawables().ToArray() }; int index = 0; foreach (var s in value) - scoresFlow.Add(new ScoreTableScore(index++, s, maxModsAmount)); + content.Add(new ScoreTableScoreRow(index++, s).CreateDrawables().ToArray()); - scoresGrid.Content = value.Select((s, i) => createRowContents(s, i).ToArray()).ToArray(); + scoresGrid.Content = content.ToArray(); + + backgroundFlow.Clear(); + for (int i = 0; i < index; i++) + backgroundFlow.Add(new ScoreTableRowBackground(i)); } } - private IEnumerable createRowContents(APIScoreInfo score, int index) - { - yield return new SpriteText - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Text = $"#{index + 1}", - Font = @"Exo2.0-Bold", - TextSize = text_size, - }; - - yield return new DrawableRank(score.Rank) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(30, 20), - FillMode = FillMode.Fit, - }; - - yield return new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Right = 20 }, - Text = $@"{score.TotalScore:N0}", - TextSize = text_size, - Font = index == 0 ? OsuFont.GetFont(weight: FontWeight.Bold) : OsuFont.Default - }; - - yield return new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Right = 20 }, - Text = $@"{score.Accuracy:P2}", - TextSize = text_size, - Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White - }; - - yield return new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new DrawableFlag(score.User.Country) - { - Size = new Vector2(20, 13), - }, - new ClickableScoreUsername - { - User = score.User, - } - } - }; - - yield return new SpriteText - { - Text = $@"{score.MaxCombo:N0}x", - TextSize = text_size, - }; - - yield return new SpriteText - { - Text = $"{score.Statistics[HitResult.Great]}", - TextSize = text_size, - Colour = score.Statistics[HitResult.Great] == 0 ? Color4.Gray : Color4.White - }; - - yield return new SpriteText - { - Text = $"{score.Statistics[HitResult.Good]}", - TextSize = text_size, - Colour = score.Statistics[HitResult.Good] == 0 ? Color4.Gray : Color4.White - }; - - yield return new SpriteText - { - Text = $"{score.Statistics[HitResult.Meh]}", - TextSize = text_size, - Colour = score.Statistics[HitResult.Meh] == 0 ? Color4.Gray : Color4.White - }; - - yield return new SpriteText - { - Text = $"{score.Statistics[HitResult.Miss]}", - TextSize = text_size, - Colour = score.Statistics[HitResult.Miss] == 0 ? Color4.Gray : Color4.White - }; - - yield return new SpriteText - { - Text = $@"{score.PP:N0}", - TextSize = text_size, - }; - - yield return new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f), - }) - }; - } - private class ScoresGrid : GridContainer { public ScoresGrid() { + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; } @@ -217,49 +88,5 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } - - private class ClickableScoreUsername : ClickableUserContainer - { - private readonly SpriteText text; - private readonly SpriteText textBold; - - public ClickableScoreUsername() - { - Add(text = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - }); - - Add(textBold = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Font = @"Exo2.0-Bold", - Alpha = 0, - }); - } - - protected override void OnUserChange(User user) - { - text.Text = textBold.Text = user.Username; - } - - protected override bool OnHover(HoverEvent e) - { - textBold.FadeIn(fade_duration, Easing.OutQuint); - text.FadeOut(fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - textBold.FadeOut(fade_duration, Easing.OutQuint); - text.FadeIn(fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs deleted file mode 100644 index 544bf34ec5..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeader.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics.Sprites; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public class ScoreTableHeader : ScoreTableRow - { - public ScoreTableHeader(int maxModsAmount) - : base(maxModsAmount) - { - RankContainer.Add(new ScoreText - { - Text = @"rank".ToUpper(), - }); - ScoreContainer.Add(new ScoreText - { - Text = @"score".ToUpper(), - }); - AccuracyContainer.Add(new ScoreText - { - Text = @"accuracy".ToUpper(), - }); - PlayerContainer.Add(new ScoreText - { - Text = @"player".ToUpper(), - }); - MaxComboContainer.Add(new ScoreText - { - Text = @"max combo".ToUpper(), - }); - HitGreatContainer.Add(new ScoreText - { - Text = "300".ToUpper(), - }); - HitGoodContainer.Add(new ScoreText - { - Text = "100".ToUpper(), - }); - HitMehContainer.Add(new ScoreText - { - Text = "50".ToUpper(), - }); - HitMissContainer.Add(new ScoreText - { - Text = @"misses".ToUpper(), - }); - PPContainer.Add(new ScoreText - { - Text = @"pp".ToUpper(), - }); - ModsContainer.Add(new ScoreText - { - Text = @"mods".ToUpper(), - }); - } - - private class ScoreText : SpriteText - { - private const float text_size = 12; - - public ScoreText() - { - TextSize = text_size; - Font = @"Exo2.0-Black"; - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs new file mode 100644 index 0000000000..a48716b71a --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTableHeaderRow : ScoreTableRow + { + protected override Drawable CreateIndexCell() => new CellText("rank"); + + protected override Drawable CreateRankCell() => new Container(); + + protected override Drawable CreateScoreCell() => new CellText("score"); + + protected override Drawable CreateAccuracyCell() => new CellText("accuracy"); + + protected override Drawable CreatePlayerCell() => new CellText("player"); + + protected override IEnumerable CreateStatisticsCells() => new[] + { + new CellText("max combo"), + new CellText("300"), + new CellText("100"), + new CellText("50"), + new CellText("miss"), + }; + + protected override Drawable CreatePpCell() => new CellText("pp"); + + protected override Drawable CreateModsCell() => new CellText("mods"); + + private class CellText : OsuSpriteText + { + public CellText(string text) + { + Text = text.ToUpper(); + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black); + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs index 3a48a0cca1..4abfb92957 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs @@ -1,183 +1,103 @@ -// 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.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTableRow : GridContainer + public abstract class ScoreTableRow { - private const float rank_position = 30; - private const float drawable_rank_position = 45; - private const float score_position = 90; - private const float accuracy_position = 170; - private const float flag_position = 220; - private const float player_position = 250; + protected const int TEXT_SIZE = 14; - private const float max_combo_position = 0.1f; - private const float hit_great_position = 0.3f; - private const float hit_good_position = 0.45f; - private const float hit_meh_position = 0.6f; - private const float hit_miss_position = 0.75f; - private const float pp_position = 0.9f; - - protected readonly Container RankContainer; - protected readonly Container DrawableRankContainer; - protected readonly Container ScoreContainer; - protected readonly Container AccuracyContainer; - protected readonly Container FlagContainer; - protected readonly Container PlayerContainer; - protected readonly Container MaxComboContainer; - protected readonly Container HitGreatContainer; - protected readonly Container HitGoodContainer; - protected readonly Container HitMehContainer; - protected readonly Container HitMissContainer; - protected readonly Container PPContainer; - protected readonly Container ModsContainer; - - public ScoreTableRow(int maxModsAmount) + public IEnumerable CreateDrawables() { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - RowDimensions = new[] + yield return new Container { - new Dimension(GridSizeMode.Absolute, 25), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Child = CreateIndexCell() }; - ColumnDimensions = new[] + + yield return new Container { - new Dimension(GridSizeMode.Absolute, 300), - new Dimension(), - new Dimension(GridSizeMode.AutoSize), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Child = CreateRankCell() }; - Content = new[] + + yield return new Container { - new Drawable[] + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = 20 }, + Child = CreateScoreCell() + }; + + yield return new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = 20 }, + Child = CreateAccuracyCell() + }; + + yield return new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = 20 }, + Child = CreatePlayerCell() + }; + + foreach (var cell in CreateStatisticsCells()) + { + yield return new Container { - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - RankContainer = new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, - X = rank_position, - }, - DrawableRankContainer = new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = drawable_rank_position, - }, - ScoreContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = score_position, - }, - AccuracyContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = accuracy_position, - }, - FlagContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = flag_position, - }, - PlayerContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = player_position, - } - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] - { - MaxComboContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = max_combo_position, - }, - HitGreatContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = hit_great_position, - }, - HitGoodContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = hit_good_position, - }, - HitMehContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = hit_meh_position, - }, - HitMissContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = hit_miss_position, - }, - PPContainer = new Container - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = pp_position, - } - } - }, - new Container - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Child = ModsContainer = new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - X = -30 * ((maxModsAmount == 0) ? 1 : maxModsAmount), - } - } - } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Child = cell + }; + } + + yield return new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Child = CreatePpCell() + }; + + yield return new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Child = CreateModsCell() }; } + + protected abstract Drawable CreateIndexCell(); + + protected abstract Drawable CreateRankCell(); + + protected abstract Drawable CreateScoreCell(); + + protected abstract Drawable CreateAccuracyCell(); + + protected abstract Drawable CreatePlayerCell(); + + protected abstract IEnumerable CreateStatisticsCells(); + + protected abstract Drawable CreatePpCell(); + + protected abstract Drawable CreateModsCell(); } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs new file mode 100644 index 0000000000..d820f4d89d --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTableRowBackground : CompositeDrawable + { + private const int fade_duration = 100; + + private readonly Box hoveredBackground; + private readonly Box background; + + public ScoreTableRowBackground(int index) + { + RelativeSizeAxes = Axes.X; + Height = 25; + + CornerRadius = 3; + Masking = true; + + InternalChildren = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + hoveredBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + }; + + if (index % 2 != 0) + background.Alpha = 0; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoveredBackground.Colour = colours.Gray4; + background.Colour = colours.Gray3; + } + + protected override bool OnHover(HoverEvent e) + { + hoveredBackground.FadeIn(fade_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoveredBackground.FadeOut(fade_duration, Easing.OutQuint); + base.OnHoverLost(e); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs deleted file mode 100644 index a54770fb39..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScore.cs +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; -using osu.Game.Users; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public class ScoreTableScore : Container - { - private const int fade_duration = 100; - private const int text_size = 14; - - private readonly Box hoveredBackground; - private readonly Box background; - - public ScoreTableScore(int index, APIScoreInfo score, int maxModsAmount) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - CornerRadius = 3; - Masking = true; - - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - hoveredBackground = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - }, - new ScoreRow(index, score, maxModsAmount), - }; - - if (index % 2 != 0) - background.Alpha = 0; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoveredBackground.Colour = colours.Gray4; - background.Colour = colours.Gray3; - } - - protected override bool OnHover(HoverEvent e) - { - hoveredBackground.FadeIn(fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoveredBackground.FadeOut(fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - - protected override bool OnClick(ClickEvent e) => true; - - private class ClickableScoreUsername : ClickableUserContainer - { - private readonly SpriteText text; - private readonly SpriteText textBold; - - public ClickableScoreUsername() - { - Add(text = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - }); - - Add(textBold = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Font = @"Exo2.0-Bold", - Alpha = 0, - }); - } - - protected override void OnUserChange(User user) - { - text.Text = textBold.Text = user.Username; - } - - protected override bool OnHover(HoverEvent e) - { - textBold.FadeIn(fade_duration, Easing.OutQuint); - text.FadeOut(fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - textBold.FadeOut(fade_duration, Easing.OutQuint); - text.FadeIn(fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } - - private class ScoreRow : ScoreTableRow - { - public ScoreRow(int index, APIScoreInfo score, int maxModsAmount) - : base(maxModsAmount) - { - SpriteText scoreText; - SpriteText accuracy; - SpriteText hitGreat; - SpriteText hitGood; - SpriteText hitMeh; - SpriteText hitMiss; - - FillFlowContainer modsContainer; - - RankContainer.Add(new SpriteText - { - Text = $"#{index + 1}", - Font = @"Exo2.0-Bold", - TextSize = text_size, - }); - DrawableRankContainer.Add(new DrawableRank(score.Rank) - { - Size = new Vector2(30, 20), - FillMode = FillMode.Fit, - }); - ScoreContainer.Add(scoreText = new SpriteText - { - Text = $@"{score.TotalScore:N0}", - TextSize = text_size, - }); - AccuracyContainer.Add(accuracy = new SpriteText - { - Text = $@"{score.Accuracy:P2}", - TextSize = text_size, - }); - FlagContainer.Add(new DrawableFlag(score.User.Country) - { - Size = new Vector2(20, 13), - }); - PlayerContainer.Add(new ClickableScoreUsername - { - User = score.User, - }); - MaxComboContainer.Add(new SpriteText - { - Text = $@"{score.MaxCombo:N0}x", - TextSize = text_size, - }); - HitGreatContainer.Add(hitGreat = new SpriteText - { - Text = $"{score.Statistics[HitResult.Great]}", - TextSize = text_size, - }); - HitGoodContainer.Add(hitGood = new SpriteText - { - Text = $"{score.Statistics[HitResult.Good]}", - TextSize = text_size, - }); - HitMehContainer.Add(hitMeh = new SpriteText - { - Text = $"{score.Statistics[HitResult.Meh]}", - TextSize = text_size, - }); - HitMissContainer.Add(hitMiss = new SpriteText - { - Text = $"{score.Statistics[HitResult.Miss]}", - TextSize = text_size, - }); - PPContainer.Add(new SpriteText - { - Text = $@"{score.PP:N0}", - TextSize = text_size, - }); - ModsContainer.Add(modsContainer = new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - }); - - if (index == 0) - scoreText.Font = @"Exo2.0-Bold"; - - accuracy.Colour = (score.Accuracy == 1) ? Color4.GreenYellow : Color4.White; - hitGreat.Colour = (score.Statistics[HitResult.Great] == 0) ? Color4.Gray : Color4.White; - hitGood.Colour = (score.Statistics[HitResult.Good] == 0) ? Color4.Gray : Color4.White; - hitMeh.Colour = (score.Statistics[HitResult.Meh] == 0) ? Color4.Gray : Color4.White; - hitMiss.Colour = (score.Statistics[HitResult.Miss] == 0) ? Color4.Gray : Color4.White; - - foreach (Mod mod in score.Mods) - modsContainer.Add(new ModIcon(mod) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f), - }); - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs new file mode 100644 index 0000000000..cd1ade934a --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -0,0 +1,168 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class ScoreTableScoreRow : ScoreTableRow + { + private readonly int index; + private readonly ScoreInfo score; + + public ScoreTableScoreRow(int index, ScoreInfo score) + { + this.index = index; + this.score = score; + } + + protected override Drawable CreateIndexCell() => new OsuSpriteText + { + Text = $"#{index + 1}", + Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold) + }; + + protected override Drawable CreateRankCell() => new DrawableRank(score.Rank) + { + Size = new Vector2(30, 20), + }; + + protected override Drawable CreateScoreCell() => new OsuSpriteText + { + Text = $@"{score.TotalScore:N0}", + Font = OsuFont.GetFont(size: TEXT_SIZE, weight: index == 0 ? FontWeight.Bold : FontWeight.Medium) + }; + + protected override Drawable CreateAccuracyCell() => new OsuSpriteText + { + Text = $@"{score.Accuracy:P2}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White + }; + + protected override Drawable CreatePlayerCell() => new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) }, + new ClickableScoreUsername { User = score.User } + } + }; + + protected override IEnumerable CreateStatisticsCells() + { + yield return new OsuSpriteText + { + Text = $@"{score.MaxCombo:N0}x", + Font = OsuFont.GetFont(size: TEXT_SIZE) + }; + + yield return new OsuSpriteText + { + Text = $"{score.Statistics[HitResult.Great]}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = score.Statistics[HitResult.Great] == 0 ? Color4.Gray : Color4.White + }; + + yield return new OsuSpriteText + { + Text = $"{score.Statistics[HitResult.Good]}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = score.Statistics[HitResult.Good] == 0 ? Color4.Gray : Color4.White + }; + + yield return new OsuSpriteText + { + Text = $"{score.Statistics[HitResult.Meh]}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = score.Statistics[HitResult.Meh] == 0 ? Color4.Gray : Color4.White + }; + + yield return new OsuSpriteText + { + Text = $"{score.Statistics[HitResult.Miss]}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = score.Statistics[HitResult.Miss] == 0 ? Color4.Gray : Color4.White + }; + } + + protected override Drawable CreatePpCell() => new OsuSpriteText + { + Text = $@"{score.PP:N0}", + Font = OsuFont.GetFont(size: TEXT_SIZE) + }; + + protected override Drawable CreateModsCell() => new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) + { + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f) + }) + }; + + private class ClickableScoreUsername : ClickableUserContainer + { + private const int fade_duration = 100; + + private readonly SpriteText text; + private readonly SpriteText textBold; + + public ClickableScoreUsername() + { + Add(text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: TEXT_SIZE) + }); + + Add(textBold = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold), + Alpha = 0, + }); + } + + protected override void OnUserChange(User user) + { + text.Text = textBold.Text = user.Username; + } + + protected override bool OnHover(HoverEvent e) + { + textBold.FadeIn(fade_duration, Easing.OutQuint); + text.FadeOut(fade_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + textBold.FadeOut(fade_duration, Easing.OutQuint); + text.FadeIn(fade_duration, Easing.OutQuint); + base.OnHoverLost(e); + } + } + } +} From 384eee33957a30c88ec2b8ff2baffa30ede3bb98 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 11:32:26 +0900 Subject: [PATCH 064/278] Remove DI requirement for the Facade in PlayerLoader --- .../Visual/TestCaseFacadeContainer.cs | 11 +++-------- osu.Game/Graphics/Containers/FacadeContainer.cs | 17 ++++++----------- osu.Game/Screens/Play/PlayerLoader.cs | 8 +++++--- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs index 0d4caff97e..6291b026f3 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual private class TestScreen : OsuScreen { private TestFacadeContainer facadeContainer; - private FacadeFlowComponent facadeFlowComponent; + private Facade facadeFlowComponent; private readonly bool randomPositions; public TestScreen(bool randomPositions = false) @@ -104,13 +104,8 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - InternalChild = facadeContainer = new TestFacadeContainer - { - Child = facadeFlowComponent = new FacadeFlowComponent - { - AutoSizeAxes = Axes.Both - } - }; + InternalChild = facadeContainer = new TestFacadeContainer(); + facadeContainer.Child = facadeFlowComponent = facadeContainer.Facade; } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index 47ba738f1c..11c256725d 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; @@ -18,19 +17,15 @@ namespace osu.Game.Graphics.Containers { protected virtual Facade CreateFacade() => new Facade(); - public Facade Facade => facade; + public readonly Facade Facade; /// /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. /// public bool Tracking; - [Cached] - private Facade facade; - private OsuLogo logo; private float facadeScale; - private Vector2 startPosition; private Easing easing; private double startTime; @@ -38,11 +33,11 @@ namespace osu.Game.Graphics.Containers public FacadeContainer() { - facade = CreateFacade(); + Facade = CreateFacade(); } /// - /// Set the logo that should track the Facade's position, as well as how it should transform to its initial position. + /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. /// /// The instance of the logo to be used for tracking. /// The scale of the facade. @@ -60,7 +55,7 @@ namespace osu.Game.Graphics.Containers this.easing = easing; } - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(facade.ScreenSpaceDrawQuad.Centre); + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(Facade.ScreenSpaceDrawQuad.Centre); protected override void UpdateAfterChildren() { @@ -69,9 +64,9 @@ namespace osu.Game.Graphics.Containers if (logo == null || !Tracking) return; - facade.Size = new Vector2(logo.SizeForFlow * facadeScale); + Facade.Size = new Vector2(logo.SizeForFlow * facadeScale); - if (facade.IsLoaded && logo.Position != logoTrackingPosition) + if (Facade.IsLoaded && logo.Position != logoTrackingPosition) { // Required for the correct position of the logo to be set with respect to logoTrackingPosition logo.RelativePositionAxes = Axes.None; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index f35eb6979d..4601cf71e0 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play facadeContainer.RelativeSizeAxes = Axes.Both; facadeContainer.Children = new Drawable[] { - info = new BeatmapMetadataDisplay(Beatmap.Value) + info = new BeatmapMetadataDisplay(Beatmap.Value, facadeContainer.Facade) { Alpha = 0, Anchor = Anchor.Centre, @@ -310,6 +310,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; + private readonly Facade facade; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -331,13 +332,14 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Facade facade) { this.beatmap = beatmap; + this.facade = facade; } [BackgroundDependencyLoader] - private void load(Facade facade) + private void load() { var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); From efeed715170c5e9e45501cabda7da80d59f947fa Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 11:37:16 +0900 Subject: [PATCH 065/278] Add comment --- osu.Game/Screens/Menu/ButtonSystem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 4c0bcd399a..7b458809b1 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu } else { + // If logo is null, we are suspending from the screen that uses this ButtonSystem. + // We should stop tracking as the facade is now out of scope. facadeContainer.Tracking = false; } } From 43c6a8d2e59a3fbdba14ce3014abaa289d32bef8 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 11:44:50 +0900 Subject: [PATCH 066/278] use a property instead --- osu.Game/Graphics/Containers/FacadeContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs index 11c256725d..0ec5e77c72 100644 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ b/osu.Game/Graphics/Containers/FacadeContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Graphics.Containers { protected virtual Facade CreateFacade() => new Facade(); - public readonly Facade Facade; + public Facade Facade { get; } /// /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. From 7239ebf5deb6b0809e453fa8e9fcd1c1b61056a5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Mar 2019 13:57:26 +0900 Subject: [PATCH 067/278] Add margin for mods --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs index 4abfb92957..8efda73270 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs @@ -80,6 +80,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = 20 }, Child = CreateModsCell() }; } From 4b1e564df2fe8d7882725ad71b744dd6ffc70f42 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 14:31:07 +0900 Subject: [PATCH 068/278] Fix test cases potentially getting stuck after 4th run --- osu.Game.Tests/Visual/TestCaseFacadeContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs index 6291b026f3..55842af867 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs @@ -163,10 +163,10 @@ namespace osu.Game.Tests.Visual public bool Ready; [BackgroundDependencyLoader] - private void load() + private void load(CancellationToken token) { // Never finish loading - while (!Ready) + while (!Ready && !token.IsCancellationRequested) Thread.Sleep(1); } } From ca7a20585dbb58b09b7426949e0ad4b28543efd5 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 17:28:53 +0900 Subject: [PATCH 069/278] Apply reviews, delete playerloader test --- ...iner.cs => TestCaseLogoFacadeContainer.cs} | 72 +++---------- .../Graphics/Containers/FacadeContainer.cs | 102 ------------------ .../Containers/LogoFacadeContainer.cs | 100 +++++++++++++++++ osu.Game/Screens/Menu/ButtonSystem.cs | 25 +++-- osu.Game/Screens/Play/PlayerLoader.cs | 70 ++++++------ 5 files changed, 161 insertions(+), 208 deletions(-) rename osu.Game.Tests/Visual/{TestCaseFacadeContainer.cs => TestCaseLogoFacadeContainer.cs} (60%) delete mode 100644 osu.Game/Graphics/Containers/FacadeContainer.cs create mode 100644 osu.Game/Graphics/Containers/LogoFacadeContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs similarity index 60% rename from osu.Game.Tests/Visual/TestCaseFacadeContainer.cs rename to osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index 55842af867..0e7f4d4bc0 100644 --- a/osu.Game.Tests/Visual/TestCaseFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -9,7 +9,6 @@ using NUnit.Framework; 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.UserInterface; using osu.Game.Configuration; @@ -24,14 +23,14 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual { - public class TestCaseFacadeContainer : ScreenTestCase + public class TestCaseLogoFacadeContainer : ScreenTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(PlayerLoader), typeof(Player), - typeof(Facade), - typeof(FacadeContainer), + typeof(LogoFacadeContainer.Facade), + typeof(LogoFacadeContainer), typeof(ButtonSystem), typeof(ButtonSystemState), typeof(Menu), @@ -43,7 +42,7 @@ namespace osu.Game.Tests.Visual private readonly Bindable uiScale = new Bindable(); - public TestCaseFacadeContainer() + public TestCaseLogoFacadeContainer() { Add(logo = new OsuLogo()); } @@ -63,20 +62,7 @@ namespace osu.Game.Tests.Visual AddStep("Move facade to random position", () => LoadScreen(new TestScreen(randomPositions))); } - [Test] - public void PlayerLoaderTest() - { - AddToggleStep("Toggle mods", b => { Beatmap.Value.Mods.Value = b ? Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }) : Enumerable.Empty(); }); - AddStep("Add new playerloader", () => LoadScreen(new TestPlayerLoader(() => new TestPlayer - { - AllowPause = false, - AllowLeadIn = false, - AllowResults = false, - Ready = false - }))); - } - - private class TestFacadeContainer : FacadeContainer + private class TestLogoFacadeContainer : LogoFacadeContainer { protected override Facade CreateFacade() => new Facade { @@ -92,8 +78,8 @@ namespace osu.Game.Tests.Visual private class TestScreen : OsuScreen { - private TestFacadeContainer facadeContainer; - private Facade facadeFlowComponent; + private TestLogoFacadeContainer logoFacadeContainer; + private LogoFacadeContainer.Facade facadeFlowComponent; private readonly bool randomPositions; public TestScreen(bool randomPositions = false) @@ -104,8 +90,8 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - InternalChild = facadeContainer = new TestFacadeContainer(); - facadeContainer.Child = facadeFlowComponent = facadeContainer.Facade; + InternalChild = logoFacadeContainer = new TestLogoFacadeContainer(); + logoFacadeContainer.Child = facadeFlowComponent = logoFacadeContainer.LogoFacade; } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -113,15 +99,15 @@ namespace osu.Game.Tests.Visual base.LogoArriving(logo, resuming); logo.FadeIn(350); logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); - facadeContainer.SetLogo(logo, 0.3f, 1000, Easing.InOutQuint); - facadeContainer.Tracking = true; + logoFacadeContainer.SetLogo(logo, 0.3f, 1000, Easing.InOutQuint); + logoFacadeContainer.Tracking = true; moveLogoFacade(); } protected override void LogoExiting(OsuLogo logo) { base.LogoExiting(logo); - facadeContainer.Tracking = false; + logoFacadeContainer.Tracking = false; } private void moveLogoFacade() @@ -136,39 +122,5 @@ namespace osu.Game.Tests.Visual Schedule(moveLogoFacade); } } - - private class FacadeFlowComponent : FillFlowContainer - { - [BackgroundDependencyLoader] - private void load(Facade facade) - { - facade.Anchor = Anchor.TopCentre; - facade.Origin = Anchor.TopCentre; - Child = facade; - } - } - - private class TestPlayerLoader : PlayerLoader - { - public TestPlayerLoader(Func player) - : base(player) - { - } - - protected override FacadeContainer CreateFacadeContainer() => new TestFacadeContainer(); - } - - private class TestPlayer : Player - { - public bool Ready; - - [BackgroundDependencyLoader] - private void load(CancellationToken token) - { - // Never finish loading - while (!Ready && !token.IsCancellationRequested) - Thread.Sleep(1); - } - } } } diff --git a/osu.Game/Graphics/Containers/FacadeContainer.cs b/osu.Game/Graphics/Containers/FacadeContainer.cs deleted file mode 100644 index 0ec5e77c72..0000000000 --- a/osu.Game/Graphics/Containers/FacadeContainer.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.MathUtils; -using osu.Game.Screens.Menu; -using osuTK; - -namespace osu.Game.Graphics.Containers -{ - /// - /// A container that creates a to be used by its children. - /// This container also updates the position and size of the Facade, and contains logic for tracking an on the Facade's position. - /// - public class FacadeContainer : Container - { - protected virtual Facade CreateFacade() => new Facade(); - - public Facade Facade { get; } - - /// - /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. - /// - public bool Tracking; - - private OsuLogo logo; - private float facadeScale; - private Vector2 startPosition; - private Easing easing; - private double startTime; - private double duration; - - public FacadeContainer() - { - Facade = CreateFacade(); - } - - /// - /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. - /// - /// The instance of the logo to be used for tracking. - /// The scale of the facade. - /// The duration of the initial transform. Default is instant. - /// The easing type of the initial transform. - public void SetLogo(OsuLogo logo, float facadeScale, double duration = 0, Easing easing = Easing.None) - { - if (logo != null) - { - this.logo = logo; - } - - this.facadeScale = facadeScale; - this.duration = duration; - this.easing = easing; - } - - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(Facade.ScreenSpaceDrawQuad.Centre); - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - if (logo == null || !Tracking) - return; - - Facade.Size = new Vector2(logo.SizeForFlow * facadeScale); - - if (Facade.IsLoaded && logo.Position != logoTrackingPosition) - { - // Required for the correct position of the logo to be set with respect to logoTrackingPosition - logo.RelativePositionAxes = Axes.None; - - // If this is our first update since tracking has started, initialize our starting values for interpolation - if (startTime == 0) - { - startTime = Time.Current; - startPosition = logo.Position; - } - - var endTime = startTime + duration; - var remainingDuration = endTime - Time.Current; - - // If our transform should be instant, our position should already be at logoTrackingPosition, thus set the blend to 0. - // If we are already past when the transform should be finished playing, set the blend to 0 so that the logo is always at the position of the facade. - var blend = duration > 0 && remainingDuration > 0 - ? (float)Interpolation.ApplyEasing(easing, remainingDuration / duration) - : 0; - - // Interpolate the position of the logo, where blend 0 is the position of the Facade, and blend 1 is where the logo was when it first began interpolating. - logo.Position = Vector2.Lerp(logoTrackingPosition, startPosition, blend); - } - } - } -} - -/// -/// A placeholder container that serves as a dummy object to denote another object's location and size. -/// -public class Facade : Container -{ -} diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs new file mode 100644 index 0000000000..a556fa697c --- /dev/null +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -0,0 +1,100 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.MathUtils; +using osu.Game.Screens.Menu; +using osuTK; + +namespace osu.Game.Graphics.Containers +{ + /// + /// A container that creates a to be used to update and track the position of an . + /// + public class LogoFacadeContainer : Container + { + protected virtual Facade CreateFacade() => new Facade(); + + public Facade LogoFacade { get; } + + /// + /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. + /// + public bool Tracking = false; + + private OsuLogo logo; + private float facadeScale; + private Vector2 startPosition; + private Easing easing; + private double? startTime; + private double duration; + + public LogoFacadeContainer() + { + LogoFacade = CreateFacade(); + } + + /// + /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. + /// + /// The instance of the logo to be used for tracking. + /// The scale of the facade. Does not actually affect the logo itself. + /// The duration of the initial transform. Default is instant. + /// The easing type of the initial transform. + public void SetLogo(OsuLogo logo, float facadeScale, double duration = 0, Easing easing = Easing.None) + { + this.logo = logo ?? throw new ArgumentNullException(nameof(logo)); + this.facadeScale = facadeScale; + this.duration = duration; + this.easing = easing; + } + + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre); + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + if (logo == null || !Tracking) + return; + + LogoFacade.Size = new Vector2(logo.SizeForFlow * facadeScale); + + if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition) + { + // Required for the correct position of the logo to be set with respect to logoTrackingPosition + logo.RelativePositionAxes = Axes.None; + + // If this is our first update since tracking has started, initialize our starting values for interpolation + if (startTime == null) + { + startTime = Time.Current; + startPosition = logo.Position; + } + + if (duration != 0) + { + double elapsedDuration = Time.Current - startTime ?? 0; + + var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); + + // Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location. + logo.Position = Vector2.Lerp(startPosition, logoTrackingPosition, mount); + } + else + { + logo.Position = logoTrackingPosition; + } + } + } + + /// + /// A placeholder container that serves as a dummy object to denote another object's location and size. + /// + public class Facade : Container + { + } + } +} diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 7b458809b1..3fad36cddb 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -48,6 +48,10 @@ namespace osu.Game.Screens.Menu private OsuLogo logo; + /// + /// Assign the that this ButtonSystem should manage the position of. + /// + /// The instance of the logo to be assigned. If null, we are suspending from the screen that uses this ButtonSystem. public void SetOsuLogo(OsuLogo logo) { this.logo = logo; @@ -55,7 +59,7 @@ namespace osu.Game.Screens.Menu if (this.logo != null) { this.logo.Action = onOsuLogo; - facadeContainer.SetLogo(logo, 0.5f); + logoFacadeContainer.SetLogo(logo, 0.5f); // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); @@ -64,9 +68,8 @@ namespace osu.Game.Screens.Menu } else { - // If logo is null, we are suspending from the screen that uses this ButtonSystem. // We should stop tracking as the facade is now out of scope. - facadeContainer.Tracking = false; + logoFacadeContainer.Tracking = false; } } @@ -79,13 +82,13 @@ namespace osu.Game.Screens.Menu private SampleChannel sampleBack; - private readonly FacadeContainer facadeContainer; + private readonly LogoFacadeContainer logoFacadeContainer; public ButtonSystem() { RelativeSizeAxes = Axes.Both; - Child = facadeContainer = new FacadeContainer + Child = logoFacadeContainer = new LogoFacadeContainer { RelativeSizeAxes = Axes.Both, Child = buttonArea = new ButtonArea() @@ -98,10 +101,10 @@ namespace osu.Game.Screens.Menu { VisibleState = ButtonSystemState.Play, }, - facadeContainer.Facade + logoFacadeContainer.LogoFacade }); - buttonArea.Flow.CentreTarget = facadeContainer.Facade; + buttonArea.Flow.CentreTarget = logoFacadeContainer.LogoFacade; } [Resolved(CanBeNull = true)] @@ -267,7 +270,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - facadeContainer.Tracking = false; + logoFacadeContainer.Tracking = false; game?.Toolbar.Hide(); @@ -295,7 +298,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - facadeContainer.Tracking = true; + logoFacadeContainer.Tracking = true; if (impact) logo.Impact(); @@ -305,14 +308,14 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); - facadeContainer.Tracking = true; + logoFacadeContainer.Tracking = true; logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; } break; case ButtonSystemState.EnteringMode: - facadeContainer.Tracking = true; + logoFacadeContainer.Tracking = true; break; } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 4601cf71e0..6ac2c8220f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -33,9 +33,7 @@ namespace osu.Game.Screens.Play private Player player; - private FacadeContainer facadeContainer; - - protected virtual FacadeContainer CreateFacadeContainer() => new FacadeContainer(); + private LogoFacadeContainer content; private BeatmapMetadataDisplay info; @@ -62,30 +60,32 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - InternalChild = facadeContainer = CreateFacadeContainer(); - facadeContainer.Anchor = Anchor.Centre; - facadeContainer.Origin = Anchor.Centre; - facadeContainer.RelativeSizeAxes = Axes.Both; - facadeContainer.Children = new Drawable[] + InternalChild = content = new LogoFacadeContainer { - info = new BeatmapMetadataDisplay(Beatmap.Value, facadeContainer.Facade) + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - Alpha = 0, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding(25), - Children = new PlayerSettingsGroup[] + info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade) { - VisualSettings = new VisualSettings(), - new InputSettings() + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding(25), + Children = new PlayerSettingsGroup[] + { + VisualSettings = new VisualSettings(), + new InputSettings() + } } } }; @@ -122,21 +122,21 @@ namespace osu.Game.Screens.Play private void contentIn() { - facadeContainer.ScaleTo(1, 650, Easing.OutQuint); - facadeContainer.FadeInFromZero(400); + content.ScaleTo(1, 650, Easing.OutQuint); + content.FadeInFromZero(400); } private void contentOut() { - facadeContainer.ScaleTo(0.7f, 300, Easing.InQuint); - facadeContainer.FadeOut(250); + content.ScaleTo(0.7f, 300, Easing.InQuint); + content.FadeOut(250); } public override void OnEntering(IScreen last) { base.OnEntering(last); - facadeContainer.ScaleTo(0.7f); + content.ScaleTo(0.7f); Background?.FadeColour(Color4.White, 800, Easing.OutQuint); contentIn(); @@ -155,15 +155,15 @@ namespace osu.Game.Screens.Play logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); - facadeContainer.SetLogo(logo, 0.3f, 500, Easing.InOutQuint); + content.SetLogo(logo, 0.3f, 500, Easing.InOutExpo); - Scheduler.AddDelayed(() => facadeContainer.Tracking = true, duration); + Scheduler.AddDelayed(() => content.Tracking = true, resuming ? 0 : 500); } protected override void LogoExiting(OsuLogo logo) { base.LogoExiting(logo); - facadeContainer.Tracking = false; + content.Tracking = false; } protected override void LoadComplete() @@ -238,7 +238,7 @@ namespace osu.Game.Screens.Play public override bool OnExiting(IScreen next) { - facadeContainer.ScaleTo(0.7f, 150, Easing.InQuint); + content.ScaleTo(0.7f, 150, Easing.InQuint); this.FadeOut(150); cancelLoad(); @@ -310,7 +310,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; - private readonly Facade facade; + private readonly LogoFacadeContainer.Facade facade; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -332,7 +332,7 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Facade facade) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, LogoFacadeContainer.Facade facade) { this.beatmap = beatmap; this.facade = facade; From 34a33b335d1e5046cd1cc5f9712f5994753d8fc9 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 17:29:38 +0900 Subject: [PATCH 070/278] oops --- osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index 0e7f4d4bc0..152b9b1706 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -13,8 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Graphics.Containers; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; From 2e3791be1ca9e67676e4b5b42be184cd7c001060 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 18:11:12 +0900 Subject: [PATCH 071/278] Fix incorrect usage of LogoFacade --- osu.Game/Screens/Play/PlayerLoader.cs | 39 ++++++++++++++------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6ac2c8220f..3f547755c1 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -65,27 +65,28 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + }; + + content.Children = new Drawable[] + { + info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade) { - info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade) + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding(25), + Children = new PlayerSettingsGroup[] { - Alpha = 0, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding(25), - Children = new PlayerSettingsGroup[] - { - VisualSettings = new VisualSettings(), - new InputSettings() - } + VisualSettings = new VisualSettings(), + new InputSettings() } } }; From 061527a260241e78b5ce479006f6c91e2b91e271 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 27 Mar 2019 20:04:01 +0900 Subject: [PATCH 072/278] Add new automated tests for logofacade, reset interpolation --- .../Visual/TestCaseLogoFacadeContainer.cs | 115 ++++++++++++++---- .../Containers/LogoFacadeContainer.cs | 11 +- osu.Game/Screens/Play/PlayerLoader.cs | 4 +- 3 files changed, 103 insertions(+), 27 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index 152b9b1706..8be0d25a86 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -7,8 +7,10 @@ using NUnit.Framework; 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.UserInterface; +using osu.Framework.Screens; using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Screens; @@ -25,7 +27,6 @@ namespace osu.Game.Tests.Visual { typeof(PlayerLoader), typeof(Player), - typeof(LogoFacadeContainer.Facade), typeof(LogoFacadeContainer), typeof(ButtonSystem), typeof(ButtonSystemState), @@ -47,36 +48,65 @@ namespace osu.Game.Tests.Visual private void load(OsuConfigManager config) { config.BindWith(OsuSetting.UIScale, uiScale); - AddSliderStep("Adjust scale", 1f, 1.5f, 1f, v => uiScale.Value = v); + AddSliderStep("Adjust scale", 0.8f, 1.5f, 1f, v => uiScale.Value = v); } + /// + /// Move the facade to 0,0, then move it to a random new location while the logo is still transforming to it. + /// Check if the logo is still tracking the facade. + /// [Test] - public void IsolatedTest() + public void MoveFacadeTest() { + TestScreen screen = null; bool randomPositions = false; AddToggleStep("Toggle move continuously", b => randomPositions = b); - AddStep("Move facade to random position", () => LoadScreen(new TestScreen(randomPositions))); + AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen(randomPositions))); + AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); + waitForMove(); + AddAssert("Logo is tracking", () => screen.IsLogoTracking); } - private class TestLogoFacadeContainer : LogoFacadeContainer + /// + /// Check if the facade is removed from the container, the logo stops tracking. + /// + [Test] + public void RemoveFacadeTest() { - protected override Facade CreateFacade() => new Facade - { - Colour = Color4.Tomato, - Alpha = 0.35f, - Child = new Box - { - Colour = Color4.Tomato, - RelativeSizeAxes = Axes.Both, - }, - }; + TestScreen screen = null; + AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen())); + AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); + AddStep("Remove facade from FacadeContainer", () => screen.RemoveFacade()); + waitForMove(); + AddAssert("Logo is not tracking", () => !screen.IsLogoTracking); } + /// + /// Check if the facade gets added to a new container, tracking starts on the new facade. + /// + [Test] + public void TransferFacadeTest() + { + TestScreen screen = null; + AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen())); + AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); + AddStep("Remove facade from FacadeContainer", () => screen.RemoveFacade()); + AddStep("Transfer facade to a new container", () => screen.TransferFacade()); + waitForMove(); + AddAssert("Logo is tracking", () => screen.IsLogoTracking); + } + + private void waitForMove() => AddWaitStep("Wait for transforms to finish", 5); + private class TestScreen : OsuScreen { - private TestLogoFacadeContainer logoFacadeContainer; - private LogoFacadeContainer.Facade facadeFlowComponent; + private LogoFacadeContainer logoFacadeContainer; + private Container transferContainer; + private Container logoFacade; private readonly bool randomPositions; + private OsuLogo logo; + private Box visualBox; + private Box transferContainerBox; public TestScreen(bool randomPositions = false) { @@ -86,13 +116,55 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - InternalChild = logoFacadeContainer = new TestLogoFacadeContainer(); - logoFacadeContainer.Child = facadeFlowComponent = logoFacadeContainer.LogoFacade; + InternalChildren = new Drawable[] + { + logoFacadeContainer = new LogoFacadeContainer + { + Alpha = 0.35f, + RelativeSizeAxes = Axes.None, + Size = new Vector2(107), + Child = visualBox = new Box + { + Colour = Color4.Tomato, + RelativeSizeAxes = Axes.Both, + } + }, + transferContainer = new Container + { + Alpha = 0.35f, + RelativeSizeAxes = Axes.None, + Size = new Vector2(107), + Child = transferContainerBox = new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + } + }, + }; + + logoFacadeContainer.Add(logoFacade = logoFacadeContainer.LogoFacade); + } + + public bool IsLogoTracking => logo.Position == logo.Parent.ToLocalSpace(logoFacadeContainer.LogoFacade.ScreenSpaceDrawQuad.Centre); + + public void RemoveFacade() + { + logoFacadeContainer.Remove(logoFacade); + visualBox.Colour = Color4.White; + moveLogoFacade(); + } + + public void TransferFacade() + { + transferContainer.Add(logoFacade); + transferContainerBox.Colour = Color4.Tomato; + moveLogoFacade(); } protected override void LogoArriving(OsuLogo logo, bool resuming) { base.LogoArriving(logo, resuming); + this.logo = logo; logo.FadeIn(350); logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); logoFacadeContainer.SetLogo(logo, 0.3f, 1000, Easing.InOutQuint); @@ -109,9 +181,10 @@ namespace osu.Game.Tests.Visual private void moveLogoFacade() { Random random = new Random(); - if (facadeFlowComponent.Transforms.Count == 0) + if (logoFacade.Transforms.Count == 0 && transferContainer.Transforms.Count == 0) { - facadeFlowComponent.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); + logoFacadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); + transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); } if (randomPositions) diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index a556fa697c..f4599e0039 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -26,8 +26,8 @@ namespace osu.Game.Graphics.Containers private OsuLogo logo; private float facadeScale; - private Vector2 startPosition; private Easing easing; + private Vector2? startPosition; private double? startTime; private double duration; @@ -49,6 +49,9 @@ namespace osu.Game.Graphics.Containers this.facadeScale = facadeScale; this.duration = duration; this.easing = easing; + + startTime = null; + startPosition = null; } private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre); @@ -68,7 +71,7 @@ namespace osu.Game.Graphics.Containers logo.RelativePositionAxes = Axes.None; // If this is our first update since tracking has started, initialize our starting values for interpolation - if (startTime == null) + if (startTime == null || startPosition == null) { startTime = Time.Current; startPosition = logo.Position; @@ -76,12 +79,12 @@ namespace osu.Game.Graphics.Containers if (duration != 0) { - double elapsedDuration = Time.Current - startTime ?? 0; + double elapsedDuration = Time.Current - startTime ?? throw new ArgumentNullException(nameof(startTime)); var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); // Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location. - logo.Position = Vector2.Lerp(startPosition, logoTrackingPosition, mount); + logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), logoTrackingPosition, mount); } else { diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 3f547755c1..72fbb378a4 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -311,7 +311,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; - private readonly LogoFacadeContainer.Facade facade; + private readonly Container facade; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -333,7 +333,7 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap, LogoFacadeContainer.Facade facade) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Container facade) { this.beatmap = beatmap; this.facade = facade; From 9b047d9b90c112013369959d23fb1703775ac52d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 28 Mar 2019 12:00:50 +0900 Subject: [PATCH 073/278] Add back menu logo transform --- osu.Game/Screens/Menu/ButtonSystem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 3fad36cddb..21305c6489 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -295,11 +295,12 @@ namespace osu.Game.Screens.Menu if (lastState == ButtonSystemState.Initial) logo.ScaleTo(0.5f, 200, Easing.In); + logoFacadeContainer.SetLogo(logo, 0.5f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); + logoFacadeContainer.Tracking = true; + logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - logoFacadeContainer.Tracking = true; - if (impact) logo.Impact(); From bfe44eb33d7df500b5031171b928c9320b347473 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 28 Mar 2019 15:40:58 +0900 Subject: [PATCH 074/278] Remove SizeForFlow magic number --- osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs | 7 ++++++- osu.Game/Graphics/Containers/LogoFacadeContainer.cs | 3 ++- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 3 ++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index 8be0d25a86..f81e70e7b0 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -145,7 +145,12 @@ namespace osu.Game.Tests.Visual logoFacadeContainer.Add(logoFacade = logoFacadeContainer.LogoFacade); } - public bool IsLogoTracking => logo.Position == logo.Parent.ToLocalSpace(logoFacadeContainer.LogoFacade.ScreenSpaceDrawQuad.Centre); + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(logoFacade.ScreenSpaceDrawQuad.Centre); + + /// + /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. + /// + public bool IsLogoTracking => Math.Abs(logo.Position.X - logoTrackingPosition.X) < 0.001f && Math.Abs(logo.Position.Y - logoTrackingPosition.Y) < 0.001f; public void RemoveFacade() { diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index f4599e0039..547af87522 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -63,7 +63,8 @@ namespace osu.Game.Graphics.Containers if (logo == null || !Tracking) return; - LogoFacade.Size = new Vector2(logo.SizeForFlow * facadeScale); + // Account for the scale of the actual logo container, as SizeForFlow only accounts for the sprite scale. + LogoFacade.Size = new Vector2(logo.SizeForFlow * logo.Scale.X * facadeScale); if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition) { diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index af697d37bd..c54ccd21b5 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Menu /// public Func Action; - public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X * 0.74f; + public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X; private readonly Sprite ripple; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 72fbb378a4..5a8c3846fa 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -156,7 +156,7 @@ namespace osu.Game.Screens.Play logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); - content.SetLogo(logo, 0.3f, 500, Easing.InOutExpo); + content.SetLogo(logo, 1.0f, 500, Easing.InOutExpo); Scheduler.AddDelayed(() => content.Tracking = true, resuming ? 0 : 500); } @@ -365,6 +365,7 @@ namespace osu.Game.Screens.Play Font = OsuFont.GetFont(size: 36, italics: true), Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, + Margin = new MarginPadding { Top = 15 }, }, new OsuSpriteText { From 039e451ab1b4eee334c937a9bcaf3320118e1f48 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 28 Mar 2019 16:09:42 +0900 Subject: [PATCH 075/278] ensure logo is where it already needs to be on resume --- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5a8c3846fa..da5abbae95 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -152,8 +152,12 @@ namespace osu.Game.Screens.Play const double duration = 300; + if (!resuming) + { + logo.MoveTo(new Vector2(0.5f), duration, Easing.In); + } + logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); - logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.FadeIn(350); content.SetLogo(logo, 1.0f, 500, Easing.InOutExpo); From 9d66a5e4b20841ed8d6222a71e5767a4fe7c6eaa Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 28 Mar 2019 16:29:35 +0900 Subject: [PATCH 076/278] Ensure logo stops tracking before suspend animation --- osu.Game/Screens/Play/PlayerLoader.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index da5abbae95..53a349f595 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -129,6 +129,9 @@ namespace osu.Game.Screens.Play private void contentOut() { + // Ensure the logo is no longer tracking before we scale the content. + content.Tracking = false; + content.ScaleTo(0.7f, 300, Easing.InQuint); content.FadeOut(250); } From f066bd11384b56ea55afb7a0439b9a6fc8de12fd Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 28 Mar 2019 16:35:15 +0900 Subject: [PATCH 077/278] Adjust facade scale now that the size is different --- osu.Game/Screens/Menu/ButtonSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 21305c6489..19b460250f 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu if (this.logo != null) { this.logo.Action = onOsuLogo; - logoFacadeContainer.SetLogo(logo, 0.5f); + logoFacadeContainer.SetLogo(logo, 0.74f); // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); @@ -295,7 +295,7 @@ namespace osu.Game.Screens.Menu if (lastState == ButtonSystemState.Initial) logo.ScaleTo(0.5f, 200, Easing.In); - logoFacadeContainer.SetLogo(logo, 0.5f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); + logoFacadeContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); logoFacadeContainer.Tracking = true; logoDelayedAction?.Cancel(); From eefc55f89bbf9ab64e94291a01c792473955645b Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 29 Mar 2019 00:20:16 -0700 Subject: [PATCH 078/278] Fix volume overlay being blocked by other floating overlays - excluding settings --- osu.Game/OsuGame.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e470d554c9..2172f5870d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -421,7 +421,6 @@ namespace osu.Game }, }, topMostOverlayContent.Add); - loadComponentSingleFile(volume = new VolumeOverlay(), floatingOverlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); loadComponentSingleFile(loginOverlay = new LoginOverlay @@ -438,7 +437,6 @@ namespace osu.Game loadComponentSingleFile(social = new SocialOverlay(), overlayContent.Add); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add); - loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset }, floatingOverlayContent.Add); loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add); loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add); @@ -456,6 +454,9 @@ namespace osu.Game Origin = Anchor.TopRight, }, floatingOverlayContent.Add); + loadComponentSingleFile(volume = new VolumeOverlay(), floatingOverlayContent.Add); + loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset }, floatingOverlayContent.Add); + loadComponentSingleFile(accountCreation = new AccountCreationOverlay(), topMostOverlayContent.Add); loadComponentSingleFile(dialogOverlay = new DialogOverlay(), topMostOverlayContent.Add); From 1ba608f01fcc3edb0f854ce4f2d6bc1e9bcd3777 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 29 Mar 2019 00:26:17 -0700 Subject: [PATCH 079/278] Remove line spacing on similar code --- osu.Game/OsuGame.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2172f5870d..9f47d545e2 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -458,9 +458,7 @@ namespace osu.Game loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset }, floatingOverlayContent.Add); loadComponentSingleFile(accountCreation = new AccountCreationOverlay(), topMostOverlayContent.Add); - loadComponentSingleFile(dialogOverlay = new DialogOverlay(), topMostOverlayContent.Add); - loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener(), topMostOverlayContent.Add); dependencies.CacheAs(idleTracker); From 352b4b20d917d34d2d8f9ec4b34e9b9323f41c46 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 29 Mar 2019 16:28:25 +0900 Subject: [PATCH 080/278] Correct the sizes of TestCaseLogoFacadeContainer --- osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index f81e70e7b0..adbf22302b 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual { Alpha = 0.35f, RelativeSizeAxes = Axes.None, - Size = new Vector2(107), + Size = new Vector2(72), Child = visualBox = new Box { Colour = Color4.Tomato, @@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual { Alpha = 0.35f, RelativeSizeAxes = Axes.None, - Size = new Vector2(107), + Size = new Vector2(72), Child = transferContainerBox = new Box { Colour = Color4.White, @@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual this.logo = logo; logo.FadeIn(350); logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); - logoFacadeContainer.SetLogo(logo, 0.3f, 1000, Easing.InOutQuint); + logoFacadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutQuint); logoFacadeContainer.Tracking = true; moveLogoFacade(); } From 952a12bb19b118fa129b8aa73551906e8baa8388 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 29 Mar 2019 16:54:34 +0900 Subject: [PATCH 081/278] Return logo relativepositionaxes on content out --- osu.Game/Screens/Play/PlayerLoader.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 53a349f595..9e6f7cf24e 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -37,6 +37,8 @@ namespace osu.Game.Screens.Play private BeatmapMetadataDisplay info; + private OsuLogo logo; + private bool hideOverlays; public override bool HideOverlaysOnEnter => hideOverlays; @@ -129,9 +131,12 @@ namespace osu.Game.Screens.Play private void contentOut() { - // Ensure the logo is no longer tracking before we scale the content. + // Ensure the logo is no longer tracking before we scale the content, and that its RelativePositionAxes have been returned. content.Tracking = false; + if (logo != null) + logo.RelativePositionAxes = Axes.Both; + content.ScaleTo(0.7f, 300, Easing.InQuint); content.FadeOut(250); } @@ -153,6 +158,8 @@ namespace osu.Game.Screens.Play { base.LogoArriving(logo, resuming); + this.logo = logo; + const double duration = 300; if (!resuming) From 698e38c4e059085a36ea2c4cfab137c05a2acab4 Mon Sep 17 00:00:00 2001 From: LeNitrous Date: Sun, 31 Mar 2019 20:10:44 +0800 Subject: [PATCH 082/278] make menu flashes and visualisation colourable by skin --- osu.Game/Screens/Menu/LogoVisualisation.cs | 24 +++++++++++- osu.Game/Screens/Menu/MenuSideFlashes.cs | 44 ++++++++++++++++++---- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index a41a12927b..8501040ca7 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -12,6 +12,9 @@ using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Skinning; +using osu.Game.Online.API; +using osu.Game.Users; using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -66,18 +69,27 @@ namespace osu.Game.Screens.Menu private IShader shader; private readonly Texture texture; + private Bindable user; + private Bindable skin; + public LogoVisualisation() { texture = Texture.WhitePixel; - AccentColour = new Color4(1, 1, 1, 0.2f); Blending = BlendingMode.Additive; } [BackgroundDependencyLoader] - private void load(ShaderManager shaders, IBindable beatmap) + private void load(ShaderManager shaders, IBindable beatmap, IAPIProvider api, SkinManager skinManager) { this.beatmap.BindTo(beatmap); shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + user = api.LocalUser.GetBoundCopy(); + skin = skinManager.CurrentSkin.GetBoundCopy(); + + user.ValueChanged += _ => changeColour(); + skin.ValueChanged += _ => changeColour(); + + changeColour(); } private void updateAmplitudes() @@ -107,6 +119,14 @@ namespace osu.Game.Screens.Menu Scheduler.AddDelayed(updateAmplitudes, time_between_updates); } + private void changeColour() + { + if (user.Value?.IsSupporter ?? false) + AccentColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? new Color4(1, 1, 1, 0.2f); + else + AccentColour = new Color4(1, 1, 1, 0.2f); + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index ce0a38ba8d..af4fa40b14 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -12,6 +12,9 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Skinning; +using osu.Game.Online.API; +using osu.Game.Users; using System; using osu.Framework.Bindables; @@ -32,6 +35,12 @@ namespace osu.Game.Screens.Menu private const double box_fade_in_time = 65; private const int box_width = 200; + private Bindable user; + private Bindable skin; + + [Resolved] + private OsuColour colours { get; set; } + public MenuSideFlashes() { EarlyActivationMilliseconds = box_fade_in_time; @@ -42,13 +51,15 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(IBindable beatmap, OsuColour colours) + private void load(IBindable beatmap, IAPIProvider api, SkinManager skinManager) { this.beatmap.BindTo(beatmap); - // linear colour looks better in this case, so let's use it for now. - Color4 gradientDark = colours.Blue.Opacity(0).ToLinear(); - Color4 gradientLight = colours.Blue.Opacity(0.6f).ToLinear(); + user = api.LocalUser.GetBoundCopy(); + skin = skinManager.CurrentSkin.GetBoundCopy(); + + user.ValueChanged += _ => changeColour(); + skin.ValueChanged += _ => changeColour(); Children = new Drawable[] { @@ -62,8 +73,7 @@ namespace osu.Game.Screens.Menu // align off-screen to make sure our edges don't become visible during parallax. X = -box_width, Alpha = 0, - Blending = BlendingMode.Additive, - Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark) + Blending = BlendingMode.Additive }, rightBox = new Box { @@ -74,10 +84,11 @@ namespace osu.Game.Screens.Menu Height = 1.5f, X = box_width, Alpha = 0, - Blending = BlendingMode.Additive, - Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight) + Blending = BlendingMode.Additive } }; + + changeColour(); } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) @@ -97,5 +108,22 @@ namespace osu.Game.Screens.Menu .Then() .FadeOut(beatLength, Easing.In); } + + private void changeColour() + { + Color4 baseColour; + + if (user.Value?.IsSupporter ?? false) + baseColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? colours.Blue; + else + baseColour = colours.Blue; + + // linear colour looks better in this case, so let's use it for now. + Color4 gradientDark = baseColour.Opacity(0).ToLinear(); + Color4 gradientLight = baseColour.Opacity(0.6f).ToLinear(); + + leftBox.Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark); + rightBox.Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight); + } } } From f45367583802f595e148947c9335cc8975c09c9a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 1 Apr 2019 10:31:20 +0900 Subject: [PATCH 083/278] Fix replays being parsed with incorrect cultures --- osu.Game/Scoring/Legacy/LegacyScoreParser.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index 51810945db..969a5bba5a 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Globalization; using System.IO; using System.Linq; using osu.Game.Beatmaps; @@ -232,7 +233,10 @@ namespace osu.Game.Scoring.Legacy if (diff < 0) continue; - replay.Frames.Add(convertFrame(new LegacyReplayFrame(lastTime, float.Parse(split[1]), float.Parse(split[2]), (ReplayButtonState)int.Parse(split[3])))); + replay.Frames.Add(convertFrame(new LegacyReplayFrame(lastTime, + float.Parse(split[1], CultureInfo.InvariantCulture), + float.Parse(split[2], CultureInfo.InvariantCulture), + (ReplayButtonState)int.Parse(split[3])))); } } From fb0bba9b37df499eb03c7953faf47cccd8ab7394 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 1 Apr 2019 11:23:07 +0900 Subject: [PATCH 084/278] Use Parsing helpers --- osu.Game/Scoring/Legacy/LegacyScoreParser.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index 969a5bba5a..d1649a6098 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -2,10 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Globalization; using System.IO; using System.Linq; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; using osu.Game.IO.Legacy; using osu.Game.Replays; @@ -225,7 +225,7 @@ namespace osu.Game.Scoring.Legacy continue; } - var diff = float.Parse(split[0]); + var diff = Parsing.ParseFloat(split[0]); lastTime += diff; // Todo: At some point we probably want to rewind and play back the negative-time frames @@ -234,9 +234,9 @@ namespace osu.Game.Scoring.Legacy continue; replay.Frames.Add(convertFrame(new LegacyReplayFrame(lastTime, - float.Parse(split[1], CultureInfo.InvariantCulture), - float.Parse(split[2], CultureInfo.InvariantCulture), - (ReplayButtonState)int.Parse(split[3])))); + Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE), + Parsing.ParseFloat(split[2], Parsing.MAX_COORDINATE_VALUE), + (ReplayButtonState)Parsing.ParseInt(split[3])))); } } From 2b3c70b2d25ce80b7876e384c8a948ddfcade5de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 Apr 2019 13:13:56 +0900 Subject: [PATCH 085/278] Refactor with constants and better method names --- osu.Game/Screens/Menu/LogoVisualisation.cs | 15 ++++++++------- osu.Game/Screens/Menu/MenuSideFlashes.cs | 14 +++++--------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 8501040ca7..8283bf7ea2 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -18,6 +18,7 @@ using osu.Game.Users; using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; namespace osu.Game.Screens.Menu { @@ -86,10 +87,8 @@ namespace osu.Game.Screens.Menu user = api.LocalUser.GetBoundCopy(); skin = skinManager.CurrentSkin.GetBoundCopy(); - user.ValueChanged += _ => changeColour(); - skin.ValueChanged += _ => changeColour(); - - changeColour(); + user.ValueChanged += _ => updateColour(); + skin.BindValueChanged(_ => updateColour(), true); } private void updateAmplitudes() @@ -119,12 +118,14 @@ namespace osu.Game.Screens.Menu Scheduler.AddDelayed(updateAmplitudes, time_between_updates); } - private void changeColour() + private void updateColour() { + Color4 defaultColour = Color4.White.Opacity(0.2f); + if (user.Value?.IsSupporter ?? false) - AccentColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? new Color4(1, 1, 1, 0.2f); + AccentColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? defaultColour; else - AccentColour = new Color4(1, 1, 1, 0.2f); + AccentColour = defaultColour; } protected override void LoadComplete() diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index af4fa40b14..95d0bf04b4 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -58,9 +58,6 @@ namespace osu.Game.Screens.Menu user = api.LocalUser.GetBoundCopy(); skin = skinManager.CurrentSkin.GetBoundCopy(); - user.ValueChanged += _ => changeColour(); - skin.ValueChanged += _ => changeColour(); - Children = new Drawable[] { leftBox = new Box @@ -88,7 +85,8 @@ namespace osu.Game.Screens.Menu } }; - changeColour(); + user.ValueChanged += _ => updateColour(); + skin.BindValueChanged(_ => updateColour(), true); } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) @@ -109,14 +107,12 @@ namespace osu.Game.Screens.Menu .FadeOut(beatLength, Easing.In); } - private void changeColour() + private void updateColour() { - Color4 baseColour; + Color4 baseColour = colours.Blue; if (user.Value?.IsSupporter ?? false) - baseColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? colours.Blue; - else - baseColour = colours.Blue; + baseColour = skin.Value.GetValue(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? baseColour; // linear colour looks better in this case, so let's use it for now. Color4 gradientDark = baseColour.Opacity(0).ToLinear(); From 2060bad3bc6212efca44429bcace0e23deac635d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 Apr 2019 13:28:14 +0900 Subject: [PATCH 086/278] Try applying minimal inspection fixes for latest Rider EAP --- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 4 ---- osu.Game/Scoring/Legacy/LegacyScoreParser.cs | 3 +++ osu.Game/Skinning/LegacySkinDecoder.cs | 10 ++-------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index c1aaa7767e..41bb740e46 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -292,7 +292,6 @@ namespace osu.Game.Rulesets.Osu.Replays { // We add intermediate frames for spinning / following a slider here. case Spinner spinner: - { Vector2 difference = startPosition - SPINNER_CENTRE; float radius = difference.Length; @@ -315,9 +314,7 @@ namespace osu.Game.Rulesets.Osu.Replays endFrame.Position = endPosition; break; - } case Slider slider: - { for (double j = FrameDelay; j < slider.Duration; j += FrameDelay) { Vector2 pos = slider.StackedPositionAt(j / slider.Duration); @@ -326,7 +323,6 @@ namespace osu.Game.Rulesets.Osu.Replays AddFrameToReplay(new OsuReplayFrame(slider.EndTime, new Vector2(slider.StackedEndPosition.X, slider.StackedEndPosition.Y), action)); break; - } } // We only want to let go of our button if we are at the end of the current replay. Otherwise something is still going on after us so we need to keep the button pressed! diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index d1649a6098..3491a5779a 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -145,6 +145,7 @@ namespace osu.Game.Scoring.Legacy score.Rank = ScoreRank.D; break; } + case 1: { int totalHits = count50 + count100 + count300 + countMiss; @@ -167,6 +168,7 @@ namespace osu.Game.Scoring.Legacy score.Rank = ScoreRank.D; break; } + case 2: { int totalHits = count50 + count100 + count300 + countMiss + countKatu; @@ -186,6 +188,7 @@ namespace osu.Game.Scoring.Legacy score.Rank = ScoreRank.D; break; } + case 3: { int totalHits = count50 + count100 + count300 + countMiss + countGeki + countKatu; diff --git a/osu.Game/Skinning/LegacySkinDecoder.cs b/osu.Game/Skinning/LegacySkinDecoder.cs index 96a9116c51..a655c884be 100644 --- a/osu.Game/Skinning/LegacySkinDecoder.cs +++ b/osu.Game/Skinning/LegacySkinDecoder.cs @@ -16,12 +16,10 @@ namespace osu.Game.Skinning { line = StripComments(line); + var pair = SplitKeyVal(line); switch (section) { case Section.General: - { - var pair = SplitKeyVal(line); - switch (pair.Key) { case @"Name": @@ -36,11 +34,8 @@ namespace osu.Game.Skinning } break; - } - case Section.Fonts: - { - var pair = SplitKeyVal(line); + case Section.Fonts: switch (pair.Key) { case "HitCirclePrefix": @@ -52,7 +47,6 @@ namespace osu.Game.Skinning } break; - } } base.ParseLine(skin, section, line); From d8af5e1c5a01df26271c5d9fa50f080ac1660514 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Apr 2019 11:56:22 +0900 Subject: [PATCH 087/278] Update in-line with drawnode changes --- .../UI/Cursor/CursorTrail.cs | 76 ++++++++++--------- osu.Game/Graphics/Backgrounds/Triangles.cs | 62 ++++++++------- osu.Game/Rulesets/Mods/ModFlashlight.cs | 61 ++++++++------- osu.Game/Screens/Menu/LogoVisualisation.cs | 61 ++++++++------- 4 files changed, 139 insertions(+), 121 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 03dbf7ac63..4aec7c634e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -43,22 +43,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly InputResampler resampler = new InputResampler(); - protected override DrawNode CreateDrawNode() => new TrailDrawNode(); - - protected override void ApplyDrawNode(DrawNode node) - { - base.ApplyDrawNode(node); - - TrailDrawNode tNode = (TrailDrawNode)node; - tNode.Shader = shader; - tNode.Texture = texture; - tNode.Size = size; - tNode.Time = time; - - for (int i = 0; i < parts.Length; ++i) - if (parts[i].InvalidationID > tNode.Parts[i].InvalidationID) - tNode.Parts[i] = parts[i]; - } + protected override DrawNode CreateDrawNode() => new TrailDrawNode(this); public CursorTrail() { @@ -167,33 +152,52 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private class TrailDrawNode : DrawNode { - public IShader Shader; - public Texture Texture; + protected new CursorTrail Source => (CursorTrail)base.Source; - public float Time; + private IShader shader; + private Texture texture; - public readonly TrailPart[] Parts = new TrailPart[max_sprites]; - public Vector2 Size; + private float time; + + private readonly TrailPart[] parts = new TrailPart[max_sprites]; + private Vector2 size; private readonly VertexBuffer vertexBuffer = new QuadVertexBuffer(max_sprites, BufferUsageHint.DynamicDraw); - public TrailDrawNode() + public TrailDrawNode(CursorTrail source) + : base(source) { for (int i = 0; i < max_sprites; i++) { - Parts[i].InvalidationID = 0; - Parts[i].WasUpdated = false; + parts[i].InvalidationID = 0; + parts[i].WasUpdated = false; + } + } + + public override void ApplyState() + { + base.ApplyState(); + + shader = Source.shader; + texture = Source.texture; + size = Source.size; + time = Source.time; + + for (int i = 0; i < Source.parts.Length; ++i) + { + if (Source.parts[i].InvalidationID > parts[i].InvalidationID) + parts[i] = Source.parts[i]; } } public override void Draw(Action vertexAction) { - Shader.GetUniform("g_FadeClock").UpdateValue(ref Time); + shader.GetUniform("g_FadeClock").UpdateValue(ref time); int updateStart = -1, updateEnd = 0; - for (int i = 0; i < Parts.Length; ++i) + for (int i = 0; i < parts.Length; ++i) { - if (Parts[i].WasUpdated) + if (parts[i].WasUpdated) { if (updateStart == -1) updateStart = i; @@ -202,22 +206,22 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor int start = i * 4; int end = start; - Vector2 pos = Parts[i].Position; - float time = Parts[i].Time; + Vector2 pos = parts[i].Position; + float localTime = parts[i].Time; - Texture.DrawQuad( - new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y), + texture.DrawQuad( + new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y), DrawColourInfo.Colour, null, v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex { Position = v.Position, TexturePosition = v.TexturePosition, - Time = time + 1, + Time = localTime + 1, Colour = v.Colour, }); - Parts[i].WasUpdated = false; + parts[i].WasUpdated = false; } else if (updateStart != -1) { @@ -232,12 +236,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor base.Draw(vertexAction); - Shader.Bind(); + shader.Bind(); - Texture.TextureGL.Bind(); + texture.TextureGL.Bind(); vertexBuffer.Draw(); - Shader.Unbind(); + shader.Unbind(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index c67d779c37..e2c7693700 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -178,64 +178,68 @@ namespace osu.Game.Graphics.Backgrounds /// The colour. protected virtual Color4 CreateTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1); - protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(); - - protected override void ApplyDrawNode(DrawNode node) - { - base.ApplyDrawNode(node); - - var trianglesNode = (TrianglesDrawNode)node; - - trianglesNode.Shader = shader; - trianglesNode.Texture = texture; - trianglesNode.Size = DrawSize; - - trianglesNode.Parts.Clear(); - trianglesNode.Parts.AddRange(parts); - } + protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(this); private class TrianglesDrawNode : DrawNode { - public IShader Shader; - public Texture Texture; + protected new Triangles Source => (Triangles)base.Source; - public readonly List Parts = new List(); - public Vector2 Size; + private IShader shader; + private Texture texture; + + private readonly List parts = new List(); + private Vector2 size; private readonly LinearBatch vertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); + public TrianglesDrawNode(Triangles source) + : base(source) + { + } + + public override void ApplyState() + { + base.ApplyState(); + + shader = Source.shader; + texture = Source.texture; + size = Source.DrawSize; + + parts.Clear(); + parts.AddRange(Source.parts); + } + public override void Draw(Action vertexAction) { base.Draw(vertexAction); - Shader.Bind(); - Texture.TextureGL.Bind(); + shader.Bind(); + texture.TextureGL.Bind(); Vector2 localInflationAmount = edge_smoothness * DrawInfo.MatrixInverse.ExtractScale().Xy; - foreach (TriangleParticle particle in Parts) + foreach (TriangleParticle particle in parts) { var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); - var size = new Vector2(2 * offset.X, offset.Y); var triangle = new Triangle( - Vector2Extensions.Transform(particle.Position * Size, DrawInfo.Matrix), - Vector2Extensions.Transform(particle.Position * Size + offset, DrawInfo.Matrix), - Vector2Extensions.Transform(particle.Position * Size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix) + Vector2Extensions.Transform(particle.Position * size, DrawInfo.Matrix), + Vector2Extensions.Transform(particle.Position * size + offset, DrawInfo.Matrix), + Vector2Extensions.Transform(particle.Position * size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix) ); ColourInfo colourInfo = DrawColourInfo.Colour; colourInfo.ApplyChild(particle.Colour); - Texture.DrawTriangle( + texture.DrawTriangle( triangle, colourInfo, null, vertexBatch.AddAction, - Vector2.Divide(localInflationAmount, size)); + Vector2.Divide(localInflationAmount, new Vector2(2 * offset.X, offset.Y))); } - Shader.Unbind(); + shader.Unbind(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 0ad99d13ff..31d3720cee 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -64,24 +64,12 @@ namespace osu.Game.Rulesets.Mods internal BindableInt Combo; private IShader shader; - protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); + protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(this); public override bool RemoveCompletedTransforms => false; public List Breaks; - protected override void ApplyDrawNode(DrawNode node) - { - base.ApplyDrawNode(node); - - var flashNode = (FlashlightDrawNode)node; - - flashNode.Shader = shader; - flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; - flashNode.FlashlightPosition = Vector2Extensions.Transform(FlashlightPosition, DrawInfo.Matrix); - flashNode.FlashlightSize = Vector2Extensions.Transform(FlashlightSize, DrawInfo.Matrix); - } - [BackgroundDependencyLoader] private void load(ShaderManager shaderManager) { @@ -136,27 +124,44 @@ namespace osu.Game.Rulesets.Mods Invalidate(Invalidation.DrawNode); } } - } - private class FlashlightDrawNode : DrawNode - { - public IShader Shader; - public Quad ScreenSpaceDrawQuad; - public Vector2 FlashlightPosition; - public Vector2 FlashlightSize; - - public override void Draw(Action vertexAction) + private class FlashlightDrawNode : DrawNode { - base.Draw(vertexAction); + protected new Flashlight Source => (Flashlight)base.Source; - Shader.Bind(); + private IShader shader; + private Quad screenSpaceDrawQuad; + private Vector2 flashlightPosition; + private Vector2 flashlightSize; - Shader.GetUniform("flashlightPos").UpdateValue(ref FlashlightPosition); - Shader.GetUniform("flashlightSize").UpdateValue(ref FlashlightSize); + public FlashlightDrawNode(Flashlight source) + : base(source) + { + } - Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); + public override void ApplyState() + { + base.ApplyState(); - Shader.Unbind(); + shader = Source.shader; + screenSpaceDrawQuad = Source.ScreenSpaceDrawQuad; + flashlightPosition = Vector2Extensions.Transform(Source.FlashlightPosition, DrawInfo.Matrix); + flashlightSize = Vector2Extensions.Transform(Source.FlashlightSize, DrawInfo.Matrix); + } + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + shader.Bind(); + + shader.GetUniform("flashlightPos").UpdateValue(ref flashlightPosition); + shader.GetUniform("flashlightSize").UpdateValue(ref flashlightSize); + + Texture.WhitePixel.DrawQuad(screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); + + shader.Unbind(); + } } } } diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 8283bf7ea2..9eab588a57 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -150,62 +150,67 @@ namespace osu.Game.Screens.Menu Invalidate(Invalidation.DrawNode, shallPropagate: false); } - protected override DrawNode CreateDrawNode() => new VisualisationDrawNode(); - - protected override void ApplyDrawNode(DrawNode node) - { - base.ApplyDrawNode(node); - - var visNode = (VisualisationDrawNode)node; - - visNode.Shader = shader; - visNode.Texture = texture; - visNode.Size = DrawSize.X; - visNode.Colour = AccentColour; - visNode.AudioData = frequencyAmplitudes; - } + protected override DrawNode CreateDrawNode() => new VisualisationDrawNode(this); private class VisualisationDrawNode : DrawNode { - public IShader Shader; - public Texture Texture; + protected new LogoVisualisation Source => (LogoVisualisation)base.Source; + + private IShader shader; + private Texture texture; //Asuming the logo is a circle, we don't need a second dimension. - public float Size; + private float size; - public Color4 Colour; - public float[] AudioData; + private Color4 colour; + private float[] audioData; private readonly QuadBatch vertexBatch = new QuadBatch(100, 10); + public VisualisationDrawNode(LogoVisualisation source) + : base(source) + { + } + + public override void ApplyState() + { + base.ApplyState(); + + shader = Source.shader; + texture = Source.texture; + size = Source.DrawSize.X; + colour = Source.AccentColour; + audioData = Source.frequencyAmplitudes; + } + public override void Draw(Action vertexAction) { base.Draw(vertexAction); - Shader.Bind(); - Texture.TextureGL.Bind(); + shader.Bind(); + texture.TextureGL.Bind(); Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy; ColourInfo colourInfo = DrawColourInfo.Colour; - colourInfo.ApplyChild(Colour); + colourInfo.ApplyChild(colour); - if (AudioData != null) + if (audioData != null) { for (int j = 0; j < visualiser_rounds; j++) { for (int i = 0; i < bars_per_visualiser; i++) { - if (AudioData[i] < amplitude_dead_zone) + if (audioData[i] < amplitude_dead_zone) continue; float rotation = MathHelper.DegreesToRadians(i / (float)bars_per_visualiser * 360 + j * 360 / visualiser_rounds); float rotationCos = (float)Math.Cos(rotation); float rotationSin = (float)Math.Sin(rotation); //taking the cos and sin to the 0..1 range - var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * Size; + var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * size; - var barSize = new Vector2(Size * (float)Math.Sqrt(2 * (1 - Math.Cos(MathHelper.DegreesToRadians(360f / bars_per_visualiser)))) / 2f, bar_length * AudioData[i]); + var barSize = new Vector2(size * (float)Math.Sqrt(2 * (1 - Math.Cos(MathHelper.DegreesToRadians(360f / bars_per_visualiser)))) / 2f, bar_length * audioData[i]); //The distance between the position and the sides of the bar. var bottomOffset = new Vector2(-rotationSin * barSize.X / 2, rotationCos * barSize.X / 2); //The distance between the bottom side of the bar and the top side. @@ -218,7 +223,7 @@ namespace osu.Game.Screens.Menu Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix) ); - Texture.DrawQuad( + texture.DrawQuad( rectangle, colourInfo, null, @@ -229,7 +234,7 @@ namespace osu.Game.Screens.Menu } } - Shader.Unbind(); + shader.Unbind(); } protected override void Dispose(bool isDisposing) From a56e29347fdcdad1618c139b6fe47f1bed276f32 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Apr 2019 14:51:28 +0900 Subject: [PATCH 088/278] Adjust namespaces --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 1 + osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteTick.cs | 1 + osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs | 2 +- osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs | 1 + osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs | 1 + osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs | 1 + osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs | 1 + osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 1 + .../Objects/Drawables/Connections/FollowPoint.cs | 1 + osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs | 1 + .../Objects/Drawables/Pieces/SpinnerBackground.cs | 1 + osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs | 1 + osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs | 1 + osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs | 1 + osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 1 + osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 1 + osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 1 + osu.Game/Graphics/Containers/ConstrainedIconContainer.cs | 1 + osu.Game/Graphics/Containers/WaveContainer.cs | 1 + osu.Game/Graphics/Cursor/OsuTooltipContainer.cs | 2 +- osu.Game/Graphics/UserInterface/DialogButton.cs | 1 + osu.Game/Graphics/UserInterface/Nub.cs | 1 + osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs | 1 + osu.Game/Graphics/UserInterface/OsuContextMenu.cs | 2 +- osu.Game/Graphics/UserInterface/TwoLayerButton.cs | 1 + osu.Game/Online/Leaderboards/LeaderboardScore.cs | 1 + osu.Game/Overlays/AccountCreationOverlay.cs | 1 + osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 1 + osu.Game/Overlays/BeatmapSet/Header.cs | 1 + osu.Game/Overlays/BeatmapSet/Info.cs | 1 + osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 1 + osu.Game/Overlays/BeatmapSetOverlay.cs | 1 + osu.Game/Overlays/Chat/ChatLine.cs | 1 + osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs | 1 + osu.Game/Overlays/Dialog/PopupDialog.cs | 1 + osu.Game/Overlays/Direct/DirectPanel.cs | 1 + osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 1 + osu.Game/Overlays/MedalOverlay.cs | 1 + osu.Game/Overlays/Music/CollectionsDropdown.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 1 + osu.Game/Overlays/MusicController.cs | 1 + osu.Game/Overlays/Notifications/Notification.cs | 1 + osu.Game/Overlays/OnScreenDisplay.cs | 1 + osu.Game/Overlays/Profile/ProfileHeader.cs | 1 + osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs | 1 + osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 1 + osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs | 1 + osu.Game/Overlays/Settings/SettingsItem.cs | 1 + osu.Game/Overlays/Social/SocialPanel.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 1 + osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 1 + osu.Game/Overlays/Toolbar/ToolbarUserButton.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- .../Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs | 1 + osu.Game/Screens/Menu/Button.cs | 1 + osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs | 1 + osu.Game/Screens/Play/GameplayMenuOverlay.cs | 1 + osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs | 1 + osu.Game/Screens/Ranking/ResultModeButton.cs | 1 + osu.Game/Screens/Ranking/Results.cs | 1 + osu.Game/Screens/Ranking/ResultsPage.cs | 1 + osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 + osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs | 1 + osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs | 1 + osu.Game/Users/UserPanel.cs | 1 + 67 files changed, 67 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 0dc3f73404..625e857156 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -6,6 +6,7 @@ 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.MathUtils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 2e18c5f2ad..b9b6d5b924 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -3,7 +3,7 @@ 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.Game.Graphics; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index f2be8d614c..9a29273282 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -7,6 +7,7 @@ using osuTK.Graphics; 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.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 82a34224f4..afd7777861 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -5,7 +5,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osuTK.Graphics; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 2baf1ad520..b515abcc86 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -7,6 +7,7 @@ using osuTK.Graphics; 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.Game.Graphics; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs index b146a33fd3..1d25a0c966 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs @@ -4,6 +4,7 @@ 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.Game.Graphics; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index 89e8cd9b5a..a0d713067d 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; 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.Game.Graphics; using osu.Game.Rulesets.UI; diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs index 03b55cbead..85880222d7 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Game.Graphics; diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index f5a9978f77..0ec1fc38d2 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -4,6 +4,7 @@ using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Rulesets.Mania.Objects.Drawables; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 3c64fe57d4..aacf3ee08d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -6,6 +6,7 @@ using osuTK.Graphics; 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.Game.Skinning; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs index 93ac8748dd..84034d3ee9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs @@ -4,6 +4,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Game.Graphics.Sprites; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs index c982f53c2b..77228e28af 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs @@ -4,6 +4,7 @@ using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs index f47617bcf6..9219fab830 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerTicks.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index ba6b27f743..0cc7858f5a 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs index 53dbe5d08e..b7db819717 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics.Backgrounds; using osuTK.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Effects; namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces { diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index bed2c554ec..e80b463481 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -5,6 +5,7 @@ using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index dbff5270d2..88d7f9a751 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -6,6 +6,7 @@ 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.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index f0f58b9b5d..5bb2767438 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -6,6 +6,7 @@ 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.Game.Graphics.Containers; diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs index c1811f37d5..f5ef291c8f 100644 --- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osuTK; namespace osu.Game.Graphics.Containers diff --git a/osu.Game/Graphics/Containers/WaveContainer.cs b/osu.Game/Graphics/Containers/WaveContainer.cs index 48131d7e86..464682a0ad 100644 --- a/osu.Game/Graphics/Containers/WaveContainer.cs +++ b/osu.Game/Graphics/Containers/WaveContainer.cs @@ -5,6 +5,7 @@ using System; 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 osuTK.Graphics; diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index 4e0ce4a3e1..7bb6396041 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -6,8 +6,8 @@ using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index dbbe5b4258..b50bf14bab 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Sprites; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Effects; using osu.Game.Graphics.Containers; using osu.Framework.Input.Events; diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 1f5195eaf1..82b09e0821 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs index d64068f74c..a8041c79fc 100644 --- a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index c72d11b57e..cea8427296 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -5,7 +5,7 @@ using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; namespace osu.Game.Graphics.UserInterface { diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index 9911a7c368..36a9aca412 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -12,6 +12,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Beatmaps.ControlPoints; using osu.Framework.Audio.Track; using System; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index da5cc76060..e4458181f6 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -8,6 +8,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; diff --git a/osu.Game/Overlays/AccountCreationOverlay.cs b/osu.Game/Overlays/AccountCreationOverlay.cs index e8e44c206e..0d376257e0 100644 --- a/osu.Game/Overlays/AccountCreationOverlay.cs +++ b/osu.Game/Overlays/AccountCreationOverlay.cs @@ -5,6 +5,7 @@ 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.Screens; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 18de87e7b4..abe954aa80 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -11,6 +11,7 @@ using osuTK; using osuTK.Graphics; using osu.Game.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 95cf9e9d04..3659769752 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 4d974a0b63..44827f0a0c 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; 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.Game.Beatmaps; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index ac4485a410..44b0d9e4f6 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index c49268bc16..82bac71f5e 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Beatmaps; diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 908ec5f026..66a6672ab1 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -8,6 +8,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs index e1f29a40e4..5e506f1e4b 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs @@ -6,6 +6,7 @@ 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.UserInterface; diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index ede2f34574..a5f5ea37eb 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -6,6 +6,7 @@ using System.Linq; 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.Input.Events; diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 2b509f370e..f413dc3771 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; 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.Input.Events; diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 8313dac50a..58d6cd10d2 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -8,6 +8,7 @@ using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index a5703eba92..6d82db5603 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -19,6 +19,7 @@ using osu.Framework.Graphics.Textures; using osuTK.Input; using osu.Framework.Graphics.Shapes; using System; +using osu.Framework.Graphics.Effects; using osu.Framework.Input.Events; using osu.Framework.MathUtils; diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs index aa93e349e8..4f59b053b6 100644 --- a/osu.Game/Overlays/Music/CollectionsDropdown.cs +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -6,7 +6,7 @@ using osuTK.Graphics; 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.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 8cbea63fe3..949090e8b8 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; 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.Game.Beatmaps; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ce2137346f..307fac11df 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -10,6 +10,7 @@ using osu.Framework.Bindables; 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; diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 7abff9252f..711b3a1eef 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Game.Graphics; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 5e45fbf081..9198455bf7 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics; using osuTK; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Transforms; using osu.Framework.Threading; using osu.Game.Configuration; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 28877c21f0..46b0726123 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -20,6 +20,7 @@ using osu.Game.Overlays.Profile.Components; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; using Humanizer; +using osu.Framework.Graphics.Effects; namespace osu.Game.Overlays.Profile { diff --git a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs b/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs index a93fefdd75..23fe6e9cd5 100644 --- a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs +++ b/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 3c69082e9d..aeea5118a7 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -7,6 +7,7 @@ using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 078c01ce92..0dbc96998a 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -16,6 +16,7 @@ using System.ComponentModel; using osu.Game.Graphics; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 02e9d48f40..e970ff6211 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -9,6 +9,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Social/SocialPanel.cs b/osu.Game/Overlays/Social/SocialPanel.cs index 738f940484..555527670a 100644 --- a/osu.Game/Overlays/Social/SocialPanel.cs +++ b/osu.Game/Overlays/Social/SocialPanel.cs @@ -5,7 +5,7 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Input.Events; using osu.Game.Users; diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 71374d5180..2b2b19b73a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -4,6 +4,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs index f729810fbc..87b18ba9f4 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetButton.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.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Game.Rulesets; using osuTK.Graphics; diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index d01eab4dab..ebfa6706d4 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osuTK; using osuTK.Input; using osuTK.Graphics; diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 356ffa5180..c9e49a09f4 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -4,7 +4,7 @@ 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.Game.Graphics; using osu.Game.Online.API; using osu.Game.Users; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 48ce055975..0d33a8b9ef 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -5,7 +5,7 @@ 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.Graphics.UserInterface; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs index 1ad69afe91..70c0cf623e 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs @@ -6,6 +6,7 @@ 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.Input.Events; diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 794fc093d3..611dd66ab3 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -16,6 +16,7 @@ using osuTK.Input; using osu.Framework.Extensions.Color4Extensions; using osu.Game.Graphics.Containers; using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index dce597b276..6ec8f2bfe5 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; 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.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index 2fac8de799..ae50e0898a 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -19,6 +19,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Input.Bindings; using Humanizer; +using osu.Framework.Graphics.Effects; namespace osu.Game.Screens.Play { diff --git a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs index 8f09c2b2bf..315bc27a79 100644 --- a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs @@ -6,6 +6,7 @@ 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.Game.Graphics; using osu.Game.Rulesets.Judgements; using osuTK; diff --git a/osu.Game/Screens/Ranking/ResultModeButton.cs b/osu.Game/Screens/Ranking/ResultModeButton.cs index 109d0195db..1383511241 100644 --- a/osu.Game/Screens/Ranking/ResultModeButton.cs +++ b/osu.Game/Screens/Ranking/ResultModeButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osuTK; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index dafb4c0aad..bebeaee00a 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -8,6 +8,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Framework.Screens; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Screens/Ranking/ResultsPage.cs b/osu.Game/Screens/Ranking/ResultsPage.cs index 1b17dda563..8776c599dd 100644 --- a/osu.Game/Screens/Ranking/ResultsPage.cs +++ b/osu.Game/Screens/Ranking/ResultsPage.cs @@ -5,6 +5,7 @@ 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.Game.Beatmaps; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index b2e08aeefd..670b5ca62c 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -22,6 +22,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Rulesets; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 3c1b7cc831..4402b25c9e 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.MathUtils; diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 0f1f49bd85..410102b607 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -4,6 +4,7 @@ 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.Input.Events; diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 1f62111a4e..fc7a544433 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -16,6 +16,7 @@ using osu.Game.Overlays; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Containers; using osu.Game.Overlays.Profile.Header; From f1952c08162ff088194ab0d19a365c57871f6553 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Apr 2019 19:55:24 +0900 Subject: [PATCH 089/278] Update font awesome usage --- osu.Desktop/Overlays/VersionManager.cs | 2 +- osu.Desktop/Updater/SimpleUpdateManager.cs | 2 +- osu.Desktop/Updater/SquirrelUpdateManager.cs | 2 +- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs | 6 +++--- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs | 4 ++-- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 6 +++--- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModGrow.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModTransform.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModWiggle.cs | 2 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs | 6 +++--- .../Objects/Drawables/Pieces/SwellSymbolPiece.cs | 2 +- .../SongSelect/TestCaseBeatmapOptionsOverlay.cs | 8 ++++---- .../UserInterface/TestCaseDialogOverlay.cs | 4 ++-- .../Visual/UserInterface/TestCasePopupDialog.cs | 2 +- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- .../Graphics/Containers/LinkFlowContainer.cs | 2 +- .../Graphics/UserInterface/BreadcrumbControl.cs | 2 +- .../Graphics/UserInterface/ExternalLinkButton.cs | 2 +- .../Graphics/UserInterface/LoadingAnimation.cs | 4 ++-- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 4 ++-- .../Graphics/UserInterface/OsuPasswordTextBox.cs | 2 +- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 2 +- .../UserInterface/OsuTabControlCheckbox.cs | 6 +++--- osu.Game/Graphics/UserInterface/SearchTextBox.cs | 2 +- osu.Game/Graphics/UserInterface/StarCounter.cs | 2 +- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 6 +++--- .../Online/Leaderboards/MessagePlaceholder.cs | 2 +- .../Leaderboards/RetrievalFailurePlaceholder.cs | 2 +- .../Online/Multiplayer/GameTypes/GameTypeTag.cs | 2 +- .../Multiplayer/GameTypes/GameTypeTagTeam.cs | 4 ++-- .../Multiplayer/GameTypes/GameTypeTimeshift.cs | 2 +- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 10 +++++----- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 4 ++-- .../BeatmapSet/Buttons/DownloadButton.cs | 2 +- .../BeatmapSet/Buttons/FavouriteButton.cs | 6 +++--- osu.Game/Overlays/Chat/ExternalLinkDialog.cs | 2 +- .../Overlays/Chat/Selection/ChannelListItem.cs | 4 ++-- osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs | 2 +- osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs | 2 +- .../Overlays/Chat/Tabs/PrivateChannelTabItem.cs | 2 +- osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs | 2 +- osu.Game/Overlays/Dialog/PopupDialog.cs | 2 +- osu.Game/Overlays/Direct/DirectGridPanel.cs | 8 ++++---- osu.Game/Overlays/Direct/DirectListPanel.cs | 8 ++++---- osu.Game/Overlays/Direct/DownloadButton.cs | 4 ++-- osu.Game/Overlays/Direct/PlayButton.cs | 4 ++-- .../KeyBinding/GlobalKeyBindingsSection.cs | 2 +- osu.Game/Overlays/KeyBindingOverlay.cs | 2 +- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- osu.Game/Overlays/MusicController.cs | 12 ++++++------ osu.Game/Overlays/Notifications/Notification.cs | 2 +- .../ProgressCompletionNotification.cs | 2 +- .../Overlays/Notifications/SimpleNotification.cs | 2 +- .../Overlays/Profile/Header/SupporterIcon.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 16 ++++++++-------- .../SearchableList/DisplayStyleControl.cs | 4 ++-- .../Overlays/Settings/Sections/AudioSection.cs | 2 +- .../Overlays/Settings/Sections/DebugSection.cs | 2 +- .../Settings/Sections/GameplaySection.cs | 2 +- .../Settings/Sections/General/LoginSettings.cs | 2 +- .../Overlays/Settings/Sections/GeneralSection.cs | 2 +- .../Settings/Sections/GraphicsSection.cs | 2 +- .../Overlays/Settings/Sections/InputSection.cs | 2 +- .../Maintenance/DeleteAllBeatmapsDialog.cs | 2 +- .../Settings/Sections/MaintenanceSection.cs | 2 +- .../Overlays/Settings/Sections/OnlineSection.cs | 2 +- .../Overlays/Settings/Sections/SkinSection.cs | 2 +- osu.Game/Overlays/Social/Header.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarChatButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs | 2 +- .../Toolbar/ToolbarNotificationButton.cs | 2 +- .../Overlays/Toolbar/ToolbarSettingsButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs | 2 +- osu.Game/Overlays/Volume/MuteButton.cs | 2 +- osu.Game/Rulesets/Mods/Mod.cs | 2 +- osu.Game/Rulesets/Mods/ModDaycore.cs | 2 +- osu.Game/Rulesets/Mods/ModWindDown.cs | 2 +- osu.Game/Rulesets/Mods/ModWindUp.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- .../Screens/Edit/Components/PlaybackControl.cs | 4 ++-- .../Compose/Components/BeatDivisorControl.cs | 4 ++-- .../Compose/Components/Timeline/TimelineArea.cs | 4 ++-- osu.Game/Screens/Menu/ButtonSystem.cs | 8 ++++---- osu.Game/Screens/Menu/Disclaimer.cs | 4 ++-- .../Match/Components/MatchLeaderboardScore.cs | 6 +++--- .../Ranking/Types/RoomLeaderboardPageInfo.cs | 2 +- osu.Game/Screens/Play/Break/BreakArrows.cs | 8 ++++---- osu.Game/Screens/Play/HUD/HoldForMenuButton.cs | 2 +- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 2 +- osu.Game/Screens/Play/SkipOverlay.cs | 6 +++--- .../Ranking/Types/LocalLeaderboardPageInfo.cs | 2 +- .../Ranking/Types/ScoreOverviewPageInfo.cs | 2 +- osu.Game/Screens/ScreenWhiteBox.cs | 2 +- .../Screens/Select/BeatmapClearScoresDialog.cs | 2 +- osu.Game/Screens/Select/BeatmapDeleteDialog.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- osu.Game/Screens/Select/ImportFromStablePopup.cs | 2 +- .../Select/Options/BeatmapOptionsButton.cs | 2 +- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 6 +++--- osu.Game/Users/UserPanel.cs | 2 +- 107 files changed, 173 insertions(+), 173 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 2998e08715..711ffa7d9e 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -110,7 +110,7 @@ namespace osu.Desktop.Overlays public UpdateCompleteNotification(string version, Action openUrl = null) { Text = $"You are now running osu!lazer {version}.\nClick to see what's new!"; - Icon = FontAwesome.CheckSquare; + Icon = FontAwesome.Solid.CheckSquare; Activated = delegate { openUrl?.Invoke($"https://osu.ppy.sh/home/changelog/lazer/{version}"); diff --git a/osu.Desktop/Updater/SimpleUpdateManager.cs b/osu.Desktop/Updater/SimpleUpdateManager.cs index 1cb47d6b58..0600804339 100644 --- a/osu.Desktop/Updater/SimpleUpdateManager.cs +++ b/osu.Desktop/Updater/SimpleUpdateManager.cs @@ -54,7 +54,7 @@ namespace osu.Desktop.Updater { Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n" + "Click here to download the new version, which can be installed over the top of your existing installation", - Icon = FontAwesome.Upload, + Icon = FontAwesome.Solid.Upload, Activated = () => { host.OpenUrlExternally(getBestUrl(latest)); diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 6ebadeb4e9..5fed2a63e1 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -159,7 +159,7 @@ namespace osu.Desktop.Updater { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.Upload, + Icon = FontAwesome.Solid.Upload, Colour = Color4.White, Size = new Vector2(20), } diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index d55f3ff159..18cc300ff9 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { Name = @"Fruit Count", Content = fruits.ToString(), - Icon = FontAwesome.CircleOutline + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Juice Stream Count", Content = juiceStreams.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Banana Shower Count", Content = bananaShowers.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle } }; } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs index 184cbf339d..dc24a344e9 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -42,13 +42,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { Name = @"Note Count", Content = notes.ToString(), - Icon = FontAwesome.CircleOutline + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Hold Note Count", Content = holdnotes.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle }, }; } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs index 7099758e3d..491d82b89e 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { Name = @"Circle Count", Content = circles.ToString(), - Icon = FontAwesome.CircleOutline + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Slider Count", Content = sliders.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Spinner Count", Content = spinners.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle } }; } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 7f94b68cc0..f3c7939a94 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => "Play with blinds on your screen."; public override string Acronym => "BL"; - public override IconUsage Icon => FontAwesome.Adjust; + public override IconUsage Icon => FontAwesome.Solid.Adjust; public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => false; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModGrow.cs b/osu.Game.Rulesets.Osu/Mods/OsuModGrow.cs index 2e93815ef0..35a5992e25 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModGrow.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModGrow.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Acronym => "GR"; - public override IconUsage Icon => FontAwesome.ArrowsV; + public override IconUsage Icon => FontAwesome.Solid.ArrowsAltV; public override ModType Type => ModType.Fun; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTransform.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTransform.cs index 31195b7878..9b079895fa 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTransform.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTransform.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public override string Name => "Transform"; public override string Acronym => "TR"; - public override IconUsage Icon => FontAwesome.Arrows; + public override IconUsage Icon => FontAwesome.Solid.ArrowsAlt; public override ModType Type => ModType.Fun; public override string Description => "Everything rotates. EVERYTHING."; public override double ScoreMultiplier => 1; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModWiggle.cs b/osu.Game.Rulesets.Osu/Mods/OsuModWiggle.cs index bdc2873d8d..17fcd03dd5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModWiggle.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModWiggle.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public override string Name => "Wiggle"; public override string Acronym => "WG"; - public override IconUsage Icon => FontAwesome.Certificate; + public override IconUsage Icon => FontAwesome.Solid.Certificate; public override ModType Type => ModType.Fun; public override string Description => "They just won't stay still..."; public override double ScoreMultiplier => 1; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index a6714690b1..edf2d90c08 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.ChevronRight + Icon = FontAwesome.Solid.ChevronRight }, restrictSize: false) }; } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 3a6ff3fcf8..ab4935e350 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(48), - Icon = FontAwesome.Asterisk, + Icon = FontAwesome.Solid.Asterisk, Shadow = false, }, } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs index 4149da67c7..b595f43fbb 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs @@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { Name = @"Hit Count", Content = hits.ToString(), - Icon = FontAwesome.CircleOutline + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Drumroll Count", Content = drumrolls.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle }, new BeatmapStatistic { Name = @"Swell Count", Content = swells.ToString(), - Icon = FontAwesome.Circle + Icon = FontAwesome.Regular.Circle } }; } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs index 569ac96c15..0ed9923924 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces new SpriteIcon { RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Asterisk, + Icon = FontAwesome.Solid.Asterisk, Shadow = false } }; diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapOptionsOverlay.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapOptionsOverlay.cs index 3cb480bab8..7d09debbd6 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapOptionsOverlay.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapOptionsOverlay.cs @@ -16,10 +16,10 @@ namespace osu.Game.Tests.Visual.SongSelect { var overlay = new BeatmapOptionsOverlay(); - overlay.AddButton(@"Remove", @"from unplayed", FontAwesome.TimesCircleOutline, Color4.Purple, null, Key.Number1); - overlay.AddButton(@"Clear", @"local scores", FontAwesome.Eraser, Color4.Purple, null, Key.Number2); - overlay.AddButton(@"Edit", @"Beatmap", FontAwesome.Pencil, Color4.Yellow, null, Key.Number3); - overlay.AddButton(@"Delete", @"Beatmap", FontAwesome.Trash, Color4.Pink, null, Key.Number4, float.MaxValue); + overlay.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, Color4.Purple, null, Key.Number1); + overlay.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, Color4.Purple, null, Key.Number2); + overlay.AddButton(@"Edit", @"Beatmap", FontAwesome.Solid.PencilAlt, Color4.Yellow, null, Key.Number3); + overlay.AddButton(@"Delete", @"Beatmap", FontAwesome.Solid.Trash, Color4.Pink, null, Key.Number4, float.MaxValue); Add(overlay); diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseDialogOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseDialogOverlay.cs index 98d6f3a149..8964d20564 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseDialogOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseDialogOverlay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("dialog #1", () => overlay.Push(new PopupDialog { - Icon = FontAwesome.TrashOutline, + Icon = FontAwesome.Regular.TrashAlt, HeaderText = @"Confirm deletion of", BodyText = @"Ayase Rie - Yuima-ru*World TVver.", Buttons = new PopupDialogButton[] @@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("dialog #2", () => overlay.Push(new PopupDialog { - Icon = FontAwesome.Gear, + Icon = FontAwesome.Solid.Cog, HeaderText = @"What do you want to do with", BodyText = "Camellia as \"Bang Riot\" - Blastix Riotz", Buttons = new PopupDialogButton[] diff --git a/osu.Game.Tests/Visual/UserInterface/TestCasePopupDialog.cs b/osu.Game.Tests/Visual/UserInterface/TestCasePopupDialog.cs index bcba7e6811..2f01f593c7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCasePopupDialog.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCasePopupDialog.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface { RelativeSizeAxes = Axes.Both, State = Framework.Graphics.Containers.Visibility.Visible, - Icon = FontAwesome.AssistiveListeningSystems, + Icon = FontAwesome.Solid.AssistiveListeningSystems, HeaderText = @"This is a test popup", BodyText = "I can say lots of stuff and even wrap my words!", Buttons = new PopupDialogButton[] diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index f0f58b9b5d..1be7411bec 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -60,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, // the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment) - Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.QuestionCircleOutline } + Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle } } }; } diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 204c83aac9..dace873b92 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers showNotImplementedError = () => notifications?.Post(new SimpleNotification { Text = @"This link type is not yet supported!", - Icon = FontAwesome.LifeSaver, + Icon = FontAwesome.Solid.LifeRing, }); } diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 8eb9b99f29..f5e57e5f27 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, Size = new Vector2(item_chevron_size), - Icon = FontAwesome.ChevronRight, + Icon = FontAwesome.Solid.ChevronRight, Margin = new MarginPadding { Left = padding }, Alpha = 0f, }); diff --git a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs index 14328930ce..8c00cae08a 100644 --- a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs +++ b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs @@ -26,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface Size = new Vector2(12); InternalChild = new SpriteIcon { - Icon = FontAwesome.ExternalLink, + Icon = FontAwesome.Solid.ExternalLinkAlt, RelativeSizeAxes = Axes.Both }; } diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index bb92d8a2a9..5a8a0da135 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -37,14 +37,14 @@ namespace osu.Game.Graphics.UserInterface Position = new Vector2(1, 1), Colour = Color4.Black, Alpha = 0.4f, - Icon = FontAwesome.CircleONotch + Icon = FontAwesome.Solid.CircleNotch }, spinner = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.CircleONotch + Icon = FontAwesome.Solid.CircleNotch } }; } diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 902fd310c5..8245de9f70 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -179,7 +179,7 @@ namespace osu.Game.Graphics.UserInterface Chevron = new SpriteIcon { AlwaysPresent = true, - Icon = FontAwesome.ChevronRight, + Icon = FontAwesome.Solid.ChevronRight, Colour = Color4.Black, Alpha = 0.5f, Size = new Vector2(8), @@ -244,7 +244,7 @@ namespace osu.Game.Graphics.UserInterface }, Icon = new SpriteIcon { - Icon = FontAwesome.ChevronDown, + Icon = FontAwesome.Solid.ChevronDown, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Margin = new MarginPadding { Right = 4 }, diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 37a13f5274..418ad038f7 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -108,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface public CapsWarning() { - Icon = FontAwesome.Warning; + Icon = FontAwesome.Solid.ExclamationTriangle; } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 0ddc88b29e..fadc905541 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -254,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface { new SpriteIcon { - Icon = FontAwesome.EllipsisH, + Icon = FontAwesome.Solid.EllipsisH, Size = new Vector2(14), Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index 557a337941..869005d05c 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -99,7 +99,7 @@ namespace osu.Game.Graphics.UserInterface icon = new SpriteIcon { Size = new Vector2(14), - Icon = FontAwesome.CircleOutline, + Icon = FontAwesome.Regular.Circle, Shadow = true, }, }, @@ -120,12 +120,12 @@ namespace osu.Game.Graphics.UserInterface if (selected.NewValue) { fadeIn(); - icon.Icon = FontAwesome.CheckCircleOutline; + icon.Icon = FontAwesome.Regular.CheckCircle; } else { fadeOut(); - icon.Icon = FontAwesome.CircleOutline; + icon.Icon = FontAwesome.Regular.Circle; } }; } diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 341f49732e..7023711aaa 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.UserInterface { new SpriteIcon { - Icon = FontAwesome.Search, + Icon = FontAwesome.Solid.Search, Origin = Anchor.CentreRight, Anchor = Anchor.CentreRight, Margin = new MarginPadding { Right = 10 }, diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs index ac6e393435..8ccf3001e3 100644 --- a/osu.Game/Graphics/UserInterface/StarCounter.cs +++ b/osu.Game/Graphics/UserInterface/StarCounter.cs @@ -143,7 +143,7 @@ namespace osu.Game.Graphics.UserInterface Child = Icon = new SpriteIcon { Size = new Vector2(star_size), - Icon = FontAwesome.Star, + Icon = FontAwesome.Solid.Star, Anchor = Anchor.Centre, Origin = Anchor.Centre, }; diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index da5cc76060..70edcc3fc8 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -258,8 +258,8 @@ namespace osu.Game.Online.Leaderboards protected virtual IEnumerable GetStatistics(ScoreInfo model) => new[] { - new LeaderboardScoreStatistic(FontAwesome.Link, "Max Combo", model.MaxCombo.ToString()), - new LeaderboardScoreStatistic(FontAwesome.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)) + new LeaderboardScoreStatistic(FontAwesome.Solid.Link, "Max Combo", model.MaxCombo.ToString()), + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)) }; protected override bool OnHover(HoverEvent e) @@ -353,7 +353,7 @@ namespace osu.Game.Online.Leaderboards Size = new Vector2(icon_size), Rotation = 45, Colour = OsuColour.FromHex(@"3087ac"), - Icon = FontAwesome.Square, + Icon = FontAwesome.Solid.Square, Shadow = true, }, new SpriteIcon diff --git a/osu.Game/Online/Leaderboards/MessagePlaceholder.cs b/osu.Game/Online/Leaderboards/MessagePlaceholder.cs index b4980444d1..ef425dacd8 100644 --- a/osu.Game/Online/Leaderboards/MessagePlaceholder.cs +++ b/osu.Game/Online/Leaderboards/MessagePlaceholder.cs @@ -12,7 +12,7 @@ namespace osu.Game.Online.Leaderboards public MessagePlaceholder(string message) { - AddIcon(FontAwesome.ExclamationCircle, cp => + AddIcon(FontAwesome.Solid.ExclamationCircle, cp => { cp.Font = cp.Font.With(size: TEXT_SIZE); cp.Padding = new MarginPadding { Right = 10 }; diff --git a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs index 9a35dbc476..801f3f8ff0 100644 --- a/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs +++ b/osu.Game/Online/Leaderboards/RetrievalFailurePlaceholder.cs @@ -41,7 +41,7 @@ namespace osu.Game.Online.Leaderboards Action = () => Action?.Invoke(), Child = icon = new SpriteIcon { - Icon = FontAwesome.Refresh, + Icon = FontAwesome.Solid.Sync, Size = new Vector2(TEXT_SIZE), Shadow = true, }, diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs index d51c5eb9bb..5ba5f1a415 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs @@ -18,7 +18,7 @@ namespace osu.Game.Online.Multiplayer.GameTypes { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.Refresh, + Icon = FontAwesome.Solid.Sync, Size = new Vector2(size), Colour = colours.Blue, Shadow = false, diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs index 266f4a77b2..ef0a00a9f0 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs @@ -26,14 +26,14 @@ namespace osu.Game.Online.Multiplayer.GameTypes { new SpriteIcon { - Icon = FontAwesome.Refresh, + Icon = FontAwesome.Solid.Sync, Size = new Vector2(size * 0.75f), Colour = colours.Blue, Shadow = false, }, new SpriteIcon { - Icon = FontAwesome.Refresh, + Icon = FontAwesome.Solid.Sync, Size = new Vector2(size * 0.75f), Colour = colours.Pink, Shadow = false, diff --git a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs index 1271556db4..1a3d2837ce 100644 --- a/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs +++ b/osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online.Multiplayer.GameTypes { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.ClockOutline, + Icon = FontAwesome.Regular.Clock, Size = new Vector2(size), Colour = colours.Blue, Shadow = false diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e470d554c9..f8ca1bc65f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -580,7 +580,7 @@ namespace osu.Game { Schedule(() => notifications.Post(new SimpleNotification { - Icon = entry.Level == LogLevel.Important ? FontAwesome.ExclamationCircle : FontAwesome.Bomb, + Icon = entry.Level == LogLevel.Important ? FontAwesome.Solid.ExclamationCircle : FontAwesome.Solid.Bomb, Text = entry.Message + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty), })); } @@ -588,7 +588,7 @@ namespace osu.Game { Schedule(() => notifications.Post(new SimpleNotification { - Icon = FontAwesome.EllipsisH, + Icon = FontAwesome.Solid.EllipsisH, Text = "Subsequent messages have been logged. Click to view log files.", Activated = () => { diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index e817b28589..8ed52dade5 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -75,10 +75,10 @@ namespace osu.Game.Overlays.BeatmapSet Direction = FillDirection.Horizontal, Children = new[] { - length = new Statistic(FontAwesome.ClockOutline, "Length") { Width = 0.25f }, - bpm = new Statistic(FontAwesome.Circle, "BPM") { Width = 0.25f }, - circleCount = new Statistic(FontAwesome.CircleOutline, "Circle Count") { Width = 0.25f }, - sliderCount = new Statistic(FontAwesome.Circle, "Slider Count") { Width = 0.25f }, + length = new Statistic(FontAwesome.Regular.Clock, "Length") { Width = 0.25f }, + bpm = new Statistic(FontAwesome.Regular.Circle, "BPM") { Width = 0.25f }, + circleCount = new Statistic(FontAwesome.Regular.Circle, "Circle Count") { Width = 0.25f }, + sliderCount = new Statistic(FontAwesome.Regular.Circle, "Slider Count") { Width = 0.25f }, }, }; } @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.CentreLeft, Origin = Anchor.Centre, - Icon = FontAwesome.Square, + Icon = FontAwesome.Solid.Square, Size = new Vector2(13), Rotation = 45, Colour = OsuColour.FromHex(@"441288"), diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 1d4f181256..baf702eebc 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -131,8 +131,8 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 5 }, Children = new[] { - plays = new Statistic(FontAwesome.PlayCircle), - favourites = new Statistic(FontAwesome.Heart), + plays = new Statistic(FontAwesome.Solid.PlayCircle), + favourites = new Statistic(FontAwesome.Solid.Heart), }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 667869e310..4a60b69a5a 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Depth = -1, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Icon = FontAwesome.Download, + Icon = FontAwesome.Solid.Download, Size = new Vector2(16), Margin = new MarginPadding { Right = 5 }, }, diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 43c14e2a58..7207739646 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.HeartOutline, + Icon = FontAwesome.Regular.Heart, Size = new Vector2(18), Shadow = false, }, @@ -59,12 +59,12 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons if (favourited.NewValue) { pink.FadeIn(200); - icon.Icon = FontAwesome.Heart; + icon.Icon = FontAwesome.Solid.Heart; } else { pink.FadeOut(200); - icon.Icon = FontAwesome.HeartOutline; + icon.Icon = FontAwesome.Regular.Heart; } }; diff --git a/osu.Game/Overlays/Chat/ExternalLinkDialog.cs b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs index bcf63672ac..dbae091fb0 100644 --- a/osu.Game/Overlays/Chat/ExternalLinkDialog.cs +++ b/osu.Game/Overlays/Chat/ExternalLinkDialog.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Chat HeaderText = "Just checking..."; BodyText = $"You are about to leave osu! and open the following link in a web browser:\n\n{url}"; - Icon = FontAwesome.Warning; + Icon = FontAwesome.Solid.ExclamationTriangle; Buttons = new PopupDialogButton[] { diff --git a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs index 85a10510ef..4d77e5f93d 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Chat.Selection { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - Icon = FontAwesome.CheckCircle, + Icon = FontAwesome.Solid.CheckCircle, Size = new Vector2(text_size), Shadow = false, Margin = new MarginPadding { Right = 10f }, @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.Chat.Selection { new SpriteIcon { - Icon = FontAwesome.User, + Icon = FontAwesome.Solid.User, Size = new Vector2(text_size - 2), Shadow = false, Margin = new MarginPadding { Top = 1 }, diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs index f8a8038878..2e7f2d5908 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabControl.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Chat.Tabs AddInternal(new SpriteIcon { - Icon = FontAwesome.Comments, + Icon = FontAwesome.Solid.Comments, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Size = new Vector2(20), diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs index e1f29a40e4..a4aefa4c4f 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelTabItem.cs @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Chat.Tabs }; } - protected virtual IconUsage DisplayIcon => FontAwesome.Hashtag; + protected virtual IconUsage DisplayIcon => FontAwesome.Solid.Hashtag; protected virtual bool ShowCloseOnHover => true; diff --git a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs index f8add20674..8aa6d6fecd 100644 --- a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Chat.Tabs private readonly OsuSpriteText username; private readonly Avatar avatarContainer; - protected override IconUsage DisplayIcon => FontAwesome.At; + protected override IconUsage DisplayIcon => FontAwesome.Solid.At; public PrivateChannelTabItem(Channel value) : base(value) diff --git a/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs b/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs index b15f568c94..bde930d4fb 100644 --- a/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs +++ b/osu.Game/Overlays/Chat/Tabs/TabCloseButton.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Chat.Tabs Anchor = Anchor.Centre, Origin = Anchor.Centre, Scale = new Vector2(0.75f), - Icon = FontAwesome.Close, + Icon = FontAwesome.Solid.TimesCircle, RelativeSizeAxes = Axes.Both, }; } diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index ede2f34574..91f42a491a 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -166,7 +166,7 @@ namespace osu.Game.Overlays.Dialog { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Icon = FontAwesome.Close, + Icon = FontAwesome.Solid.TimesCircle, Size = new Vector2(50), }, }, diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index b8168f692a..eb73a50f99 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -186,8 +186,8 @@ namespace osu.Game.Overlays.Direct Margin = new MarginPadding { Top = vertical_padding, Right = vertical_padding }, Children = new[] { - new Statistic(FontAwesome.PlayCircle, SetInfo.OnlineInfo?.PlayCount ?? 0), - new Statistic(FontAwesome.Heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), + new Statistic(FontAwesome.Solid.PlayCircle, SetInfo.OnlineInfo?.PlayCount ?? 0), + new Statistic(FontAwesome.Solid.Heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, statusContainer = new FillFlowContainer @@ -206,12 +206,12 @@ namespace osu.Game.Overlays.Direct if (SetInfo.OnlineInfo?.HasVideo ?? false) { - statusContainer.Add(new IconPill(FontAwesome.Film)); + statusContainer.Add(new IconPill(FontAwesome.Solid.Film)); } if (SetInfo.OnlineInfo?.HasStoryboard ?? false) { - statusContainer.Add(new IconPill(FontAwesome.Image)); + statusContainer.Add(new IconPill(FontAwesome.Solid.Image)); } statusContainer.Add(new BeatmapSetOnlineStatusPill diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 518f6e498a..d645fd3bda 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -161,8 +161,8 @@ namespace osu.Game.Overlays.Direct Direction = FillDirection.Vertical, Children = new Drawable[] { - new Statistic(FontAwesome.PlayCircle, SetInfo.OnlineInfo?.PlayCount ?? 0), - new Statistic(FontAwesome.Heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), + new Statistic(FontAwesome.Solid.PlayCircle, SetInfo.OnlineInfo?.PlayCount ?? 0), + new Statistic(FontAwesome.Solid.Heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), new FillFlowContainer { Anchor = Anchor.TopRight, @@ -211,12 +211,12 @@ namespace osu.Game.Overlays.Direct if (SetInfo.OnlineInfo?.HasVideo ?? false) { - statusContainer.Add(new IconPill(FontAwesome.Film) { IconSize = new Vector2(20) }); + statusContainer.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) }); } if (SetInfo.OnlineInfo?.HasStoryboard ?? false) { - statusContainer.Add(new IconPill(FontAwesome.Image) { IconSize = new Vector2(20) }); + statusContainer.Add(new IconPill(FontAwesome.Solid.Image) { IconSize = new Vector2(20) }); } statusContainer.Add(new BeatmapSetOnlineStatusPill diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 7fc145d635..6107dc3af3 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(13), - Icon = FontAwesome.Download, + Icon = FontAwesome.Solid.Download, }, checkmark = new SpriteIcon { @@ -57,7 +57,7 @@ namespace osu.Game.Overlays.Direct Origin = Anchor.Centre, X = 8, Size = Vector2.Zero, - Icon = FontAwesome.Check, + Icon = FontAwesome.Solid.Check, } } } diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 05ef5c8496..6daebb3c15 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Direct Origin = Anchor.Centre, FillMode = FillMode.Fit, RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Play, + Icon = FontAwesome.Solid.Play, }, loadingAnimation = new LoadingAnimation { @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Direct private void playingStateChanged(ValueChangedEvent e) { - icon.Icon = e.NewValue ? FontAwesome.Stop : FontAwesome.Play; + icon.Icon = e.NewValue ? FontAwesome.Solid.Stop : FontAwesome.Solid.Play; icon.FadeColour(e.NewValue || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); if (e.NewValue) diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index fb524e32c3..7e33d7ba27 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -9,7 +9,7 @@ namespace osu.Game.Overlays.KeyBinding { public class GlobalKeyBindingsSection : SettingsSection { - public override IconUsage Icon => FontAwesome.Globe; + public override IconUsage Icon => FontAwesome.Solid.Globe; public override string Header => "Global"; public GlobalKeyBindingsSection(GlobalActionContainer manager) diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index 6259f39c66..b223d4701d 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays Y = -15, Size = new Vector2(15), Shadow = true, - Icon = FontAwesome.ChevronLeft + Icon = FontAwesome.Solid.ChevronLeft }, new OsuSpriteText { diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 96e9cc9ca7..df37a1b2c7 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -164,7 +164,7 @@ namespace osu.Game.Overlays.Music Anchor = Anchor.TopLeft; Origin = Anchor.TopLeft; Size = new Vector2(12); - Icon = FontAwesome.Bars; + Icon = FontAwesome.Solid.Bars; Alpha = 0f; Margin = new MarginPadding { Left = 5, Top = 2 }; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ce2137346f..b24c6c3508 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -148,7 +148,7 @@ namespace osu.Game.Overlays Anchor = Anchor.Centre, Origin = Anchor.Centre, Action = prev, - Icon = FontAwesome.StepBackward, + Icon = FontAwesome.Solid.StepBackward, }, playButton = new MusicIconButton { @@ -157,14 +157,14 @@ namespace osu.Game.Overlays Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), Action = play, - Icon = FontAwesome.PlayCircleOutline, + Icon = FontAwesome.Regular.PlayCircle, }, nextButton = new MusicIconButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, Action = () => next(), - Icon = FontAwesome.StepForward, + Icon = FontAwesome.Solid.StepForward, }, } }, @@ -173,7 +173,7 @@ namespace osu.Game.Overlays Origin = Anchor.Centre, Anchor = Anchor.CentreRight, Position = new Vector2(-bottom_black_area_height / 2, 0), - Icon = FontAwesome.Bars, + Icon = FontAwesome.Solid.Bars, Action = () => playlist.ToggleVisibility(), }, } @@ -264,13 +264,13 @@ namespace osu.Game.Overlays progressBar.EndTime = track.Length; progressBar.CurrentTime = track.CurrentTime; - playButton.Icon = track.IsRunning ? FontAwesome.PauseCircleOutline : FontAwesome.PlayCircleOutline; + playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } else { progressBar.CurrentTime = 0; progressBar.EndTime = 1; - playButton.Icon = FontAwesome.PlayCircleOutline; + playButton.Icon = FontAwesome.Regular.PlayCircle; } } diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 7abff9252f..522e039cdb 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -175,7 +175,7 @@ namespace osu.Game.Overlays.Notifications { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.TimesCircle, + Icon = FontAwesome.Solid.TimesCircle, Size = new Vector2(20), } }; diff --git a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs index d5993e1f79..feffb4fa66 100644 --- a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Notifications { public ProgressCompletionNotification() { - Icon = FontAwesome.Check; + Icon = FontAwesome.Solid.Check; } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 26852242d2..3a3136b1ea 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Notifications } } - private IconUsage icon = FontAwesome.InfoCircle; + private IconUsage icon = FontAwesome.Solid.InfoCircle; public IconUsage Icon { diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs index 7b07617e2e..5c9126dbe0 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Heart, + Icon = FontAwesome.Solid.Heart, Scale = new Vector2(0.45f), } }; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 28877c21f0..138e522cd7 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -415,16 +415,16 @@ namespace osu.Game.Overlays.Profile websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); } - tryAddInfoRightLine(FontAwesome.MapMarker, user.Location); - tryAddInfoRightLine(FontAwesome.HeartOutline, user.Interests); - tryAddInfoRightLine(FontAwesome.Suitcase, user.Occupation); + tryAddInfoRightLine(FontAwesome.Solid.MapMarker, user.Location); + tryAddInfoRightLine(FontAwesome.Regular.Heart, user.Interests); + tryAddInfoRightLine(FontAwesome.Solid.Suitcase, user.Occupation); infoTextRight.NewParagraph(); if (!string.IsNullOrEmpty(user.Twitter)) - tryAddInfoRightLine(FontAwesome.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfoRightLine(FontAwesome.Gamepad, user.Discord); - tryAddInfoRightLine(FontAwesome.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); - tryAddInfoRightLine(FontAwesome.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfoRightLine(FontAwesome.Globe, websiteWithoutProtcol, user.Website); + tryAddInfoRightLine(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); + tryAddInfoRightLine(FontAwesome.Solid.Gamepad, user.Discord); + tryAddInfoRightLine(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + tryAddInfoRightLine(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + tryAddInfoRightLine(FontAwesome.Solid.Globe, websiteWithoutProtcol, user.Website); if (user.Statistics != null) { diff --git a/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs index 48be91ea23..0808cc8fcc 100644 --- a/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs +++ b/osu.Game/Overlays/SearchableList/DisplayStyleControl.cs @@ -37,8 +37,8 @@ namespace osu.Game.Overlays.SearchableList Direction = FillDirection.Horizontal, Children = new[] { - new DisplayStyleToggleButton(FontAwesome.ThLarge, PanelDisplayStyle.Grid, DisplayStyle), - new DisplayStyleToggleButton(FontAwesome.ListUl, PanelDisplayStyle.List, DisplayStyle), + new DisplayStyleToggleButton(FontAwesome.Solid.ThLarge, PanelDisplayStyle.Grid, DisplayStyle), + new DisplayStyleToggleButton(FontAwesome.Solid.ListUl, PanelDisplayStyle.List, DisplayStyle), }, }, Dropdown = new SlimEnumDropdown diff --git a/osu.Game/Overlays/Settings/Sections/AudioSection.cs b/osu.Game/Overlays/Settings/Sections/AudioSection.cs index ea7011ea01..772f5c2039 100644 --- a/osu.Game/Overlays/Settings/Sections/AudioSection.cs +++ b/osu.Game/Overlays/Settings/Sections/AudioSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class AudioSection : SettingsSection { public override string Header => "Audio"; - public override IconUsage Icon => FontAwesome.VolumeUp; + public override IconUsage Icon => FontAwesome.Solid.VolumeUp; public AudioSection() { diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index d90bb9be10..0149cab802 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class DebugSection : SettingsSection { public override string Header => "Debug"; - public override IconUsage Icon => FontAwesome.Bug; + public override IconUsage Icon => FontAwesome.Solid.Bug; public DebugSection() { diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index e69a19b447..97d9d3c697 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections public class GameplaySection : SettingsSection { public override string Header => "Gameplay"; - public override IconUsage Icon => FontAwesome.CircleOutline; + public override IconUsage Icon => FontAwesome.Regular.Circle; public GameplaySection() { diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 078c01ce92..e4ddc53e17 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -363,7 +363,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.CircleOutline, + Icon = FontAwesome.Regular.Circle, Size = new Vector2(14), }); diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index f571d5ff7c..d9947f16cc 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class GeneralSection : SettingsSection { public override string Header => "General"; - public override IconUsage Icon => FontAwesome.Gear; + public override IconUsage Icon => FontAwesome.Solid.Cog; public GeneralSection() { diff --git a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs index 92746d5117..3d6086d3ea 100644 --- a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class GraphicsSection : SettingsSection { public override string Header => "Graphics"; - public override IconUsage Icon => FontAwesome.Laptop; + public override IconUsage Icon => FontAwesome.Solid.Laptop; public GraphicsSection() { diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index d193277a6b..6a3f8783b0 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class InputSection : SettingsSection { public override string Header => "Input"; - public override IconUsage Icon => FontAwesome.KeyboardOutline; + public override IconUsage Icon => FontAwesome.Regular.Keyboard; public InputSection(KeyBindingOverlay keyConfig) { diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/DeleteAllBeatmapsDialog.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/DeleteAllBeatmapsDialog.cs index 7ab3629e12..a124501454 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/DeleteAllBeatmapsDialog.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/DeleteAllBeatmapsDialog.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { BodyText = "Everything?"; - Icon = FontAwesome.TrashOutline; + Icon = FontAwesome.Regular.TrashAlt; HeaderText = @"Confirm deletion of"; Buttons = new PopupDialogButton[] { diff --git a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs index 41530e20ca..0f3acd5b7f 100644 --- a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections public class MaintenanceSection : SettingsSection { public override string Header => "Maintenance"; - public override IconUsage Icon => FontAwesome.Wrench; + public override IconUsage Icon => FontAwesome.Solid.Wrench; public MaintenanceSection() { diff --git a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs index f9f5d99c84..80295690c0 100644 --- a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs +++ b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections public class OnlineSection : SettingsSection { public override string Header => "Online"; - public override IconUsage Icon => FontAwesome.Globe; + public override IconUsage Icon => FontAwesome.Solid.GlobeAsia; public OnlineSection() { diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 79b9076a52..100022bd13 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections public override string Header => "Skin"; - public override IconUsage Icon => FontAwesome.PaintBrush; + public override IconUsage Icon => FontAwesome.Solid.PaintBrush; private readonly Bindable dropdownBindable = new Bindable { Default = SkinInfo.Default }; private readonly Bindable configBindable = new Bindable(); diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index bf07c343e6..22bca9b421 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Social protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); protected override SocialTab DefaultTab => SocialTab.AllPlayers; - protected override IconUsage Icon => FontAwesome.Users; + protected override IconUsage Icon => FontAwesome.Solid.Users; protected override Drawable CreateHeaderText() { diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 59d7a18a34..a7f2a0e8d0 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Toolbar new ToolbarMusicButton(), //new ToolbarButton //{ - // Icon = FontAwesome.search + // Icon = FontAwesome.Solid.search //}, userButton = new ToolbarUserButton(), new ToolbarNotificationButton(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index 8ea21e88b5..ad0e5be551 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarChatButton() { - SetIcon(FontAwesome.Comments); + SetIcon(FontAwesome.Solid.Comments); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 18a116127c..6f5e703a66 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -9,7 +9,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarHomeButton() { - Icon = FontAwesome.Home; + Icon = FontAwesome.Solid.Home; TooltipMain = "Home"; TooltipSub = "Return to the main menu"; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index 7f4c9d455e..f03df2ed93 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarMusicButton() { - Icon = FontAwesome.Music; + Icon = FontAwesome.Solid.Music; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index b3bd82ae38..dbd6c557d3 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Toolbar public ToolbarNotificationButton() { - Icon = FontAwesome.Bars; + Icon = FontAwesome.Solid.Bars; TooltipMain = "Notifications"; TooltipSub = "Waiting for 'ya"; diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index 4e48ffd034..08f8f867fd 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSettingsButton() { - Icon = FontAwesome.Gear; + Icon = FontAwesome.Solid.Cog; TooltipMain = "Settings"; TooltipSub = "Change your settings"; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index 769fa520cb..5e353d3319 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarSocialButton() { - Icon = FontAwesome.Users; + Icon = FontAwesome.Solid.Users; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 090e443a0c..2b1f78243b 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Volume Current.ValueChanged += muted => { - icon.Icon = muted.NewValue ? FontAwesome.VolumeOff : FontAwesome.VolumeUp; + icon.Icon = muted.NewValue ? FontAwesome.Solid.VolumeOff : FontAwesome.Solid.VolumeUp; icon.Margin = new MarginPadding { Left = muted.NewValue ? width / 2 - 15 : width / 2 - 10 }; //Magic numbers to line up both icons because they're different widths }; Current.TriggerChange(); diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index be2ff33730..d2d0a5bb26 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods /// The icon of this mod. /// [JsonIgnore] - public virtual IconUsage Icon => FontAwesome.Question; + public virtual IconUsage Icon => FontAwesome.Solid.Question; /// /// The type of this mod. diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 0dd5d7b815..7e6d959119 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mods { public override string Name => "Daycore"; public override string Acronym => "DC"; - public override IconUsage Icon => FontAwesome.Question; + public override IconUsage Icon => FontAwesome.Solid.Question; public override string Description => "Whoaaaaa..."; public override void ApplyToClock(IAdjustableClock clock) diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index eccd848c48..5d71c8950b 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods public override string Name => "Wind Down"; public override string Acronym => "WD"; public override string Description => "Sloooow doooown..."; - public override IconUsage Icon => FontAwesome.ChevronCircleDown; + public override IconUsage Icon => FontAwesome.Solid.ChevronCircleDown; public override double ScoreMultiplier => 1.0; protected override double FinalRateAdjustment => -0.25; diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index d430c291cb..aae85cec19 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods public override string Name => "Wind Up"; public override string Acronym => "WU"; public override string Description => "Can you keep up?"; - public override IconUsage Icon => FontAwesome.ChevronCircleUp; + public override IconUsage Icon => FontAwesome.Solid.ChevronCircleUp; public override double ScoreMultiplier => 1.0; protected override double FinalRateAdjustment => 0.5; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 013fffb7cb..cdfe02b60b 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets public virtual HitObjectComposer CreateHitObjectComposer() => null; - public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.QuestionCircle }; + public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.QuestionCircle }; public abstract string Description { get; } diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 6d590780b0..f5c9f74f62 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Edit.Components Origin = Anchor.Centre, Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), - Icon = FontAwesome.PlayCircleOutline, + Icon = FontAwesome.Regular.PlayCircle, Action = togglePause, Padding = new MarginPadding { Left = 20 } }, @@ -89,7 +89,7 @@ namespace osu.Game.Screens.Edit.Components { base.Update(); - playButton.Icon = adjustableClock.IsRunning ? FontAwesome.PauseCircleOutline : FontAwesome.PlayCircleOutline; + playButton.Icon = adjustableClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } private class PlaybackTabControl : OsuTabControl diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 1f13797497..9a7ac8dfd0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -94,13 +94,13 @@ namespace osu.Game.Screens.Edit.Compose.Components { new DivisorButton { - Icon = FontAwesome.ChevronLeft, + Icon = FontAwesome.Solid.ChevronLeft, Action = beatDivisor.Previous }, new DivisorText(beatDivisor), new DivisorButton { - Icon = FontAwesome.ChevronRight, + Icon = FontAwesome.Solid.ChevronRight, Action = beatDivisor.Next } }, diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index 2bed231da7..863a120fc3 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { RelativeSizeAxes = Axes.Y, Height = 0.5f, - Icon = FontAwesome.SearchPlus, + Icon = FontAwesome.Solid.SearchPlus, Action = () => changeZoom(1) }, new TimelineButton @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.Y, Height = 0.5f, - Icon = FontAwesome.SearchMinus, + Icon = FontAwesome.Solid.SearchMinus, Action = () => changeZoom(-1) }, } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index bcd24fd83e..d3cf23dab8 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Menu buttonArea.AddRange(new[] { - new Button(@"settings", string.Empty, FontAwesome.Gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), + new Button(@"settings", string.Empty, FontAwesome.Solid.Cog, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), backButton = new Button(@"back", @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH) { VisibleState = ButtonSystemState.Play, @@ -106,8 +106,8 @@ namespace osu.Game.Screens.Menu [BackgroundDependencyLoader(true)] private void load(AudioManager audio, IdleTracker idleTracker, GameHost host) { - buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P)); - buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.Users, new Color4(94, 63, 186, 255), onMulti, 0, Key.M)); + buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.Solid.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P)); + buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.Solid.Users, new Color4(94, 63, 186, 255), onMulti, 0, Key.M)); buttonsPlay.Add(new Button(@"chart", @"button-generic-select", OsuIcon.Charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke())); buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play); @@ -135,7 +135,7 @@ namespace osu.Game.Screens.Menu notifications?.Post(new SimpleNotification { Text = "You gotta be logged in to multi 'yo!", - Icon = FontAwesome.Globe + Icon = FontAwesome.Solid.Globe }); return; diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 170209207b..0130a5143b 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Menu { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Icon = FontAwesome.Warning, + Icon = FontAwesome.Solid.ExclamationTriangle, Size = new Vector2(icon_size), Y = icon_y, }, @@ -128,7 +128,7 @@ namespace osu.Game.Screens.Menu supportFlow.AddText(" to help support the game", format); } - heart = supportFlow.AddIcon(FontAwesome.Heart, t => + heart = supportFlow.AddIcon(FontAwesome.Solid.Heart, t => { t.Padding = new MarginPadding { Left = 5 }; t.Font = t.Font.With(size: 12); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index 2734c55ce7..92074abe4b 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -25,9 +25,9 @@ namespace osu.Game.Screens.Multi.Match.Components protected override IEnumerable GetStatistics(ScoreInfo model) => new[] { - new LeaderboardScoreStatistic(FontAwesome.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), - new LeaderboardScoreStatistic(FontAwesome.Refresh, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), - new LeaderboardScoreStatistic(FontAwesome.Check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedBeatmaps.ToString()), + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)), + new LeaderboardScoreStatistic(FontAwesome.Solid.Sync, "Total Attempts", ((APIRoomScoreInfo)model).TotalAttempts.ToString()), + new LeaderboardScoreStatistic(FontAwesome.Solid.Check, "Completed Beatmaps", ((APIRoomScoreInfo)model).CompletedBeatmaps.ToString()), }; } } diff --git a/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs index b03fafbd13..dcfad8458f 100644 --- a/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs +++ b/osu.Game/Screens/Multi/Ranking/Types/RoomLeaderboardPageInfo.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Multi.Ranking.Types this.beatmap = beatmap; } - public IconUsage Icon => FontAwesome.Users; + public IconUsage Icon => FontAwesome.Solid.Users; public string Name => "Room Leaderboard"; diff --git a/osu.Game/Screens/Play/Break/BreakArrows.cs b/osu.Game/Screens/Play/Break/BreakArrows.cs index e0238f6814..4b96fa666a 100644 --- a/osu.Game/Screens/Play/Break/BreakArrows.cs +++ b/osu.Game/Screens/Play/Break/BreakArrows.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Play.Break Anchor = Anchor.Centre, Origin = Anchor.CentreRight, X = -glow_icon_offscreen_offset, - Icon = FontAwesome.ChevronRight, + Icon = FontAwesome.Solid.ChevronRight, BlurSigma = new Vector2(glow_icon_blur_sigma), Size = new Vector2(glow_icon_size), }, @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play.Break Anchor = Anchor.Centre, Origin = Anchor.CentreLeft, X = glow_icon_offscreen_offset, - Icon = FontAwesome.ChevronLeft, + Icon = FontAwesome.Solid.ChevronLeft, BlurSigma = new Vector2(glow_icon_blur_sigma), Size = new Vector2(glow_icon_size), }, @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play.Break Origin = Anchor.CentreRight, Alpha = 0.7f, X = -blurred_icon_offscreen_offset, - Icon = FontAwesome.ChevronRight, + Icon = FontAwesome.Solid.ChevronRight, BlurSigma = new Vector2(blurred_icon_blur_sigma), Size = new Vector2(blurred_icon_size), }, @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Play.Break Origin = Anchor.CentreLeft, Alpha = 0.7f, X = blurred_icon_offscreen_offset, - Icon = FontAwesome.ChevronLeft, + Icon = FontAwesome.Solid.ChevronLeft, BlurSigma = new Vector2(blurred_icon_blur_sigma), Size = new Vector2(blurred_icon_size), }, diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index 03843eeb90..6883f246e4 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -129,7 +129,7 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(15), - Icon = FontAwesome.Close + Icon = FontAwesome.Solid.TimesCircle }, } }; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index d243ff24a3..90424ec007 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Play.PlayerSettings Origin = Anchor.Centre, Anchor = Anchor.CentreRight, Position = new Vector2(-15, 0), - Icon = FontAwesome.Bars, + Icon = FontAwesome.Solid.Bars, Scale = new Vector2(0.75f), Action = () => Expanded = !Expanded, }, diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 78ed742bfa..738877232d 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -259,9 +259,9 @@ namespace osu.Game.Screens.Play Direction = FillDirection.Horizontal, Children = new[] { - new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.ChevronRight }, - new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.ChevronRight }, - new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.ChevronRight }, + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.Solid.ChevronRight }, + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.Solid.ChevronRight }, + new SpriteIcon { Size = new Vector2(15), Shadow = true, Icon = FontAwesome.Solid.ChevronRight }, } }, new OsuSpriteText diff --git a/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs b/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs index e563eb8116..fe183c5f89 100644 --- a/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs +++ b/osu.Game/Screens/Ranking/Types/LocalLeaderboardPageInfo.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Ranking.Types this.beatmap = beatmap; } - public IconUsage Icon => FontAwesome.User; + public IconUsage Icon => FontAwesome.Solid.User; public string Name => @"Local Leaderboard"; diff --git a/osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs b/osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs index 2d9b3b9ef9..424dbff6f6 100644 --- a/osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs +++ b/osu.Game/Screens/Ranking/Types/ScoreOverviewPageInfo.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Ranking.Types { public class ScoreOverviewPageInfo : IResultPageInfo { - public IconUsage Icon => FontAwesome.Asterisk; + public IconUsage Icon => FontAwesome.Solid.Asterisk; public string Name => "Overview"; private readonly ScoreInfo score; diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs index f471cab063..d6766c2b49 100644 --- a/osu.Game/Screens/ScreenWhiteBox.cs +++ b/osu.Game/Screens/ScreenWhiteBox.cs @@ -113,7 +113,7 @@ namespace osu.Game.Screens { new SpriteIcon { - Icon = FontAwesome.UniversalAccess, + Icon = FontAwesome.Solid.UniversalAccess, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Size = new Vector2(50), diff --git a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs index aa579ac665..c9b6ca7bb3 100644 --- a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs +++ b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Select public BeatmapClearScoresDialog(BeatmapInfo beatmap, Action onCompletion) { BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; - Icon = FontAwesome.Eraser; + Icon = FontAwesome.Solid.Eraser; HeaderText = @"Clearing all local scores. Are you sure?"; Buttons = new PopupDialogButton[] { diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index a1adaff1d8..5fb72e4151 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Select { BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; - Icon = FontAwesome.TrashOutline; + Icon = FontAwesome.Regular.TrashAlt; HeaderText = @"Confirm deletion of"; Buttons = new PopupDialogButton[] { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index b2e08aeefd..d32387c1d3 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -293,14 +293,14 @@ namespace osu.Game.Screens.Select labels.Add(new InfoLabel(new BeatmapStatistic { Name = "Length", - Icon = FontAwesome.ClockOutline, + Icon = FontAwesome.Regular.Clock, Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic { Name = "BPM", - Icon = FontAwesome.Circle, + Icon = FontAwesome.Regular.Circle, Content = getBPMRange(b), })); @@ -378,7 +378,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"441288"), - Icon = FontAwesome.Square, + Icon = FontAwesome.Solid.Square, Rotation = 45, }, new SpriteIcon diff --git a/osu.Game/Screens/Select/ImportFromStablePopup.cs b/osu.Game/Screens/Select/ImportFromStablePopup.cs index f1cc3d632c..54e4c096f6 100644 --- a/osu.Game/Screens/Select/ImportFromStablePopup.cs +++ b/osu.Game/Screens/Select/ImportFromStablePopup.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Select HeaderText = @"You have no beatmaps!"; BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps (and skins)?"; - Icon = FontAwesome.Plane; + Icon = FontAwesome.Solid.Plane; Buttons = new PopupDialogButton[] { diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 0f1f49bd85..a9616ee535 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -141,7 +141,7 @@ namespace osu.Game.Screens.Select.Options Anchor = Anchor.TopCentre, Size = new Vector2(30), Shadow = true, - Icon = FontAwesome.Close, + Icon = FontAwesome.Solid.TimesCircle, Margin = new MarginPadding { Bottom = 5, diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 6a10e86198..340ceb6864 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load(OsuColour colours) { - BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Pencil, colours.Yellow, () => + BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => { ValidForResume = false; Edit(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9ac8e26ec0..b60e693cbf 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -228,9 +228,9 @@ namespace osu.Game.Screens.Select Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); Footer.AddButton(@"options", colours.Blue, BeatmapOptions, Key.F3); - BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue); - BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.TimesCircleOutline, colours.Purple, null, Key.Number1); - BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo), Key.Number2); + BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue); + BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null, Key.Number1); + BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo), Key.Number2); } if (this.beatmaps == null) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 1f62111a4e..e745aa54c8 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -166,7 +166,7 @@ namespace osu.Game.Users { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.CircleOutline, + Icon = FontAwesome.Regular.Circle, Shadow = true, Size = new Vector2(14), }, From bc1077ed73b2f237e4a52bf6aa2e13af0b310578 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Apr 2019 19:55:34 +0900 Subject: [PATCH 090/278] Remove remaining FontAwesome reference --- osu.Game/Graphics/OsuFont.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Graphics/OsuFont.cs b/osu.Game/Graphics/OsuFont.cs index 26112430f6..c8a736f49a 100644 --- a/osu.Game/Graphics/OsuFont.cs +++ b/osu.Game/Graphics/OsuFont.cs @@ -42,8 +42,6 @@ namespace osu.Game.Graphics { case Typeface.Exo: return "Exo2.0"; - case Typeface.FontAwesome: - return "FontAwesome"; case Typeface.Venera: return "Venera"; } @@ -101,7 +99,6 @@ namespace osu.Game.Graphics public enum Typeface { Exo, - FontAwesome, Venera, } From bcd51afea1686f874b120cc043906d3d32ecf021 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Apr 2019 19:55:46 +0900 Subject: [PATCH 091/278] Fix osu! icon font name mismatch --- osu.Game/Graphics/OsuIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/OsuIcon.cs b/osu.Game/Graphics/OsuIcon.cs index 52fb31553d..982e9dacab 100644 --- a/osu.Game/Graphics/OsuIcon.cs +++ b/osu.Game/Graphics/OsuIcon.cs @@ -7,7 +7,7 @@ namespace osu.Game.Graphics { public static class OsuIcon { - public static IconUsage Get(int icon) => new IconUsage((char)icon, "OsuFont"); + public static IconUsage Get(int icon) => new IconUsage((char)icon, "osuFont"); // ruleset icons in circles public static IconUsage RulesetOsu => Get(0xe000); From 072954e4c05fd274c276dd43d361b101d510cf95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 Apr 2019 21:00:05 +0900 Subject: [PATCH 092/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 52c53503ee..f3c648cf02 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9ecc7d4632..7ce7329246 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From e9269dc83bb5df8db8e9bf470cf9f263ff42ee27 Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Tue, 2 Apr 2019 23:57:31 +0800 Subject: [PATCH 093/278] Prevent unnecessary query in OsuGame::PresentBeatmap This resolves issue #4575 --- osu.Game/OsuGame.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f8ca1bc65f..9ab09d1122 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -254,6 +254,12 @@ namespace osu.Game if (menuScreen.IsCurrentScreen()) menuScreen.LoadToSolo(); + // we might even already be at the song + if (Beatmap.Value.BeatmapSetInfo.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) + { + return; + } + // Use first beatmap available for current ruleset, else switch ruleset. var first = databasedSet.Beatmaps.Find(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First(); From ab4be3b75f1ae455a18d21fc3609c96e9dbab00c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 15:20:38 +0900 Subject: [PATCH 094/278] General refactoring --- .../TestCaseBeatmapScoresContainer.cs | 1 + .../Graphics/Containers/OsuHoverContainer.cs | 4 +- .../Scores/ClickableUserContainer.cs | 29 ++++---- .../BeatmapSet/Scores/DrawableTopScore.cs | 66 ++++++++----------- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 2 +- 5 files changed, 48 insertions(+), 54 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs index c72d12c09c..4a38f98810 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs @@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual.SongSelect { public override IReadOnlyList RequiredTypes => new[] { + typeof(DrawableTopScore), typeof(ScoresContainer), typeof(ScoreTable), typeof(ScoreTableRow), diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index 091499b7cd..880807c8b4 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -12,12 +12,12 @@ namespace osu.Game.Graphics.Containers { public class OsuHoverContainer : OsuClickableContainer { + protected const float FADE_DURATION = 500; + protected Color4 HoverColour; protected Color4 IdleColour = Color4.White; - protected const float FADE_DURATION = 500; - protected virtual IEnumerable EffectTargets => new[] { Content }; protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs index cf1c3d7fcf..2448ae17f8 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs @@ -13,6 +13,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private UserProfileOverlay profile; + protected ClickableUserContainer() + { + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader(true)] + private void load(UserProfileOverlay profile) + { + this.profile = profile; + } + private User user; public User User @@ -20,26 +31,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores get => user; set { - if (user == value) return; + if (user == value) + return; user = value; - OnUserChange(user); + OnUserChanged(user); } } - protected ClickableUserContainer() - { - AutoSizeAxes = Axes.Both; - } - - protected abstract void OnUserChange(User user); - - [BackgroundDependencyLoader(true)] - private void load(UserProfileOverlay profile) - { - this.profile = profile; - } + protected abstract void OnUserChanged(User user); protected override bool OnClick(ClickEvent e) { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 82905d065e..e3141624b5 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -19,6 +19,7 @@ using osu.Game.Users; using osuTK; using osuTK.Graphics; using System.Collections.Generic; +using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -164,7 +165,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 20, }, date = new SpriteText { @@ -263,67 +263,59 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float username_fade_duration = 500; - private readonly Box underscore; - private readonly Container underscoreContainer; - private readonly SpriteText text; + private readonly FillFlowContainer hoverContainer; - private Color4 hoverColour; - - public float TextSize - { - set - { - if (text.TextSize == value) - return; - - text.TextSize = value; - } - get => text.TextSize; - } + private readonly SpriteText normalText; + private readonly SpriteText hoveredText; public ClickableTopScoreUsername() { - Add(underscoreContainer = new Container + var font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true); + + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - Height = 1, - Child = underscore = new Box + normalText = new OsuSpriteText { Font = font }, + hoverContainer = new FillFlowContainer { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Alpha = 0, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 1), + Children = new Drawable[] + { + hoveredText = new OsuSpriteText { Font = font }, + new Box + { + BypassAutoSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + Height = 1 + } + } } - }); - Add(text = new SpriteText - { - Font = @"Exo2.0-BoldItalic", - }); + }; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - hoverColour = underscore.Colour = colours.Blue; - underscoreContainer.Position = new Vector2(0, TextSize / 2 - 1); + hoverContainer.Colour = colours.Blue; } - protected override void OnUserChange(User user) + protected override void OnUserChanged(User user) { - text.Text = user.Username; + normalText.Text = hoveredText.Text = user.Username; } protected override bool OnHover(HoverEvent e) { - text.FadeColour(hoverColour, username_fade_duration, Easing.OutQuint); - underscore.FadeIn(username_fade_duration, Easing.OutQuint); + hoverContainer.FadeIn(username_fade_duration, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - text.FadeColour(Color4.White, username_fade_duration, Easing.OutQuint); - underscore.FadeOut(username_fade_duration, Easing.OutQuint); + hoverContainer.FadeOut(username_fade_duration, Easing.OutQuint); base.OnHoverLost(e); } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs index cd1ade934a..a0c6db9a56 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - protected override void OnUserChange(User user) + protected override void OnUserChanged(User user) { text.Text = textBold.Text = user.Username; } From 1dad1523632352769cfab479de52af7609c0e1b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 15:37:22 +0900 Subject: [PATCH 095/278] Correctly handle nvika/inspectcode return codes --- build/build.cake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/build.cake b/build/build.cake index 81deeb3bc7..3269bbf1c0 100644 --- a/build/build.cake +++ b/build/build.cake @@ -46,7 +46,9 @@ Task("InspectCode") OutputFile = "inspectcodereport.xml", }); - StartProcess(nVikaToolPath, @"parsereport ""inspectcodereport.xml"" --treatwarningsaserrors"); + int returnCode = StartProcess(nVikaToolPath, $@"parsereport ""{inspectcodereport}"" --treatwarningsaserrors"); + if (returnCode != 0) + throw new Exception($"inspectcode failed with return code {returnCode}"); }); Task("CodeFileSanity") From 7f425059aecbc83a0f8b12873fd95f789c8c5858 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 15:41:22 +0900 Subject: [PATCH 096/278] Adjust transforms --- .../Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 2 +- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index e3141624b5..3bcb44ab94 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -261,7 +261,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class ClickableTopScoreUsername : ClickableUserContainer { - private const float username_fade_duration = 500; + private const float username_fade_duration = 150; private readonly FillFlowContainer hoverContainer; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs index a0c6db9a56..83901cc662 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -145,22 +145,19 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } - protected override void OnUserChanged(User user) - { - text.Text = textBold.Text = user.Username; - } + protected override void OnUserChanged(User user) => text.Text = textBold.Text = user.Username; protected override bool OnHover(HoverEvent e) { - textBold.FadeIn(fade_duration, Easing.OutQuint); - text.FadeOut(fade_duration, Easing.OutQuint); + textBold.Show(); + text.Hide(); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - textBold.FadeOut(fade_duration, Easing.OutQuint); - text.FadeIn(fade_duration, Easing.OutQuint); + textBold.Hide(); + text.Show(); base.OnHoverLost(e); } } From dff58ab4edb52c2faec7eb241b6b50602cd1d432 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 15:41:33 +0900 Subject: [PATCH 097/278] Initial cleanup pass of DrawableTopScore --- .../BeatmapSet/Scores/DrawableTopScore.cs | 201 +++++++----------- 1 file changed, 72 insertions(+), 129 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 3bcb44ab94..66ef2a30a3 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -43,15 +43,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly SpriteText date; private readonly DrawableRank rank; - private readonly AutoSizedInfoColumn totalScore; - private readonly AutoSizedInfoColumn accuracy; - private readonly MediumInfoColumn maxCombo; - - private readonly SmallInfoColumn hitGreat; - private readonly SmallInfoColumn hitGood; - private readonly SmallInfoColumn hitMeh; - private readonly SmallInfoColumn hitMiss; - private readonly SmallInfoColumn pp; + private readonly SpriteText totalScoreText; + private readonly SpriteText accuracyText; + private readonly SpriteText maxComboText; + private readonly SpriteText hitGreatText; + private readonly SpriteText hitGoodText; + private readonly SpriteText hitMehText; + private readonly SpriteText hitMissText; + private readonly SpriteText ppText; private readonly ModsInfoColumn modsInfo; @@ -72,17 +71,16 @@ namespace osu.Game.Overlays.BeatmapSet.Scores date.Text = $@"achieved {score.Date.Humanize()}"; rank.UpdateRank(score.Rank); - totalScore.Value = $@"{score.TotalScore:N0}"; - accuracy.Value = $@"{score.Accuracy:P2}"; - maxCombo.Value = $@"{score.MaxCombo:N0}x"; + totalScoreText.Text = $@"{score.TotalScore:N0}"; + accuracyText.Text = $@"{score.Accuracy:P2}"; + maxComboText.Text = $@"{score.MaxCombo:N0}x"; - hitGreat.Value = $"{score.Statistics[HitResult.Great]}"; - hitGood.Value = $"{score.Statistics[HitResult.Good]}"; - hitMeh.Value = $"{score.Statistics[HitResult.Meh]}"; - hitMiss.Value = $"{score.Statistics[HitResult.Miss]}"; - pp.Value = $@"{score.PP:N0}"; + hitGreatText.Text = $"{score.Statistics[HitResult.Great]}"; + hitGoodText.Text = $"{score.Statistics[HitResult.Good]}"; + hitMehText.Text = $"{score.Statistics[HitResult.Meh]}"; + hitMissText.Text = $"{score.Statistics[HitResult.Miss]}"; + ppText.Text = $@"{score.PP:N0}"; - modsInfo.ClearMods(); modsInfo.Mods = score.Mods; } } @@ -91,8 +89,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - CornerRadius = 10; + Masking = true; + CornerRadius = 10; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, @@ -100,6 +99,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Radius = 1, Offset = new Vector2(0, 1), }; + + var smallFont = OsuFont.GetFont(size: 20); + var largeFont = OsuFont.GetFont(size: 25); + Children = new Drawable[] { background = new Box @@ -208,12 +211,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - hitGreat = new SmallInfoColumn("300", 20), - hitGood = new SmallInfoColumn("100", 20), - hitMeh = new SmallInfoColumn("50", 20), - hitMiss = new SmallInfoColumn("misses", 20), - pp = new SmallInfoColumn("pp", 20), - modsInfo = new ModsInfoColumn("mods"), + new InfoColumn("300", hitGreatText = new OsuSpriteText { Font = smallFont }), + new InfoColumn("100", hitGoodText = new OsuSpriteText { Font = smallFont }), + new InfoColumn("50", hitMehText = new OsuSpriteText { Font = smallFont }), + new InfoColumn("misses", hitMissText = new OsuSpriteText { Font = smallFont }), + new InfoColumn("pp", ppText = new OsuSpriteText { Font = smallFont }), + modsInfo = new ModsInfoColumn(), } }, new FillFlowContainer @@ -225,9 +228,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - totalScore = new AutoSizedInfoColumn("Total Score"), - accuracy = new AutoSizedInfoColumn("Accuracy"), - maxCombo = new MediumInfoColumn("Max Combo"), + new InfoColumn("total score", totalScoreText = new OsuSpriteText { Font = largeFont }), + new InfoColumn("accuracy", accuracyText = new OsuSpriteText { Font = largeFont }), + new InfoColumn("max combo", maxComboText = new OsuSpriteText { Font = largeFont }) } }, } @@ -302,10 +305,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores hoverContainer.Colour = colours.Blue; } - protected override void OnUserChanged(User user) - { - normalText.Text = hoveredText.Text = user.Username; - } + protected override void OnUserChanged(User user) => normalText.Text = hoveredText.Text = user.Username; protected override bool OnHover(HoverEvent e) { @@ -320,38 +320,32 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private class DrawableInfoColumn : FillFlowContainer + private class InfoColumn : CompositeDrawable { - private const float header_text_size = 12; + private readonly Box separator; - private readonly Box line; - - protected DrawableInfoColumn(string header) + public InfoColumn(string title, Drawable content) { - AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; - Spacing = new Vector2(0, 2); - Children = new Drawable[] + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer { - new Container + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new[] { - AutoSizeAxes = Axes.X, - Height = header_text_size, - Child = new SpriteText + new OsuSpriteText { - TextSize = 12, - Text = header.ToUpper(), - Font = @"Exo2.0-Black", - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - Height = 2, - Child = line = new Box + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), + Text = title.ToUpper() + }, + separator = new Box { - RelativeSizeAxes = Axes.Both, - } + RelativeSizeAxes = Axes.X, + Height = 2 + }, + content } }; } @@ -359,96 +353,45 @@ namespace osu.Game.Overlays.BeatmapSet.Scores [BackgroundDependencyLoader] private void load(OsuColour colours) { - line.Colour = colours.Gray5; + separator.Colour = colours.Gray5; } } - private class ModsInfoColumn : DrawableInfoColumn + private class ModsInfoColumn : InfoColumn { private readonly FillFlowContainer modsContainer; + public ModsInfoColumn() + : this(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal + }) + { + } + + private ModsInfoColumn(FillFlowContainer modsContainer) + : base("mods", modsContainer) + { + this.modsContainer = modsContainer; + } + public IEnumerable Mods { set { + modsContainer.Clear(); + foreach (Mod mod in value) + { modsContainer.Add(new ModIcon(mod) { AutoSizeAxes = Axes.Both, Scale = new Vector2(0.3f), }); + } } } - - public ModsInfoColumn(string header) - : base(header) - { - AutoSizeAxes = Axes.Both; - Add(modsContainer = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - }); - } - - public void ClearMods() => modsContainer.Clear(); - } - - private class TextInfoColumn : DrawableInfoColumn - { - private readonly SpriteText valueText; - - public string Value - { - set - { - if (valueText.Text == value) - return; - - valueText.Text = value; - } - get => valueText.Text; - } - - protected TextInfoColumn(string header, float valueTextSize = 25) - : base(header) - { - Add(valueText = new SpriteText - { - TextSize = valueTextSize, - }); - } - } - - private class AutoSizedInfoColumn : TextInfoColumn - { - public AutoSizedInfoColumn(string header, float valueTextSize = 25) - : base(header, valueTextSize) - { - AutoSizeAxes = Axes.Both; - } - } - - private class MediumInfoColumn : TextInfoColumn - { - private const float width = 70; - - public MediumInfoColumn(string header, float valueTextSize = 25) - : base(header, valueTextSize) - { - Width = width; - } - } - - private class SmallInfoColumn : TextInfoColumn - { - private const float width = 40; - - public SmallInfoColumn(string header, float valueTextSize = 25) - : base(header, valueTextSize) - { - Width = width; - } } } } From f8d53a1e30b2f3471ac7712983dc8af703a79272 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 15:43:36 +0900 Subject: [PATCH 098/278] Fix variable mismatch --- build/build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.cake b/build/build.cake index 3269bbf1c0..f1b7fa4036 100644 --- a/build/build.cake +++ b/build/build.cake @@ -46,7 +46,7 @@ Task("InspectCode") OutputFile = "inspectcodereport.xml", }); - int returnCode = StartProcess(nVikaToolPath, $@"parsereport ""{inspectcodereport}"" --treatwarningsaserrors"); + int returnCode = StartProcess(nVikaToolPath, $@"parsereport ""inspectcodereport.xml"" --treatwarningsaserrors"); if (returnCode != 0) throw new Exception($"inspectcode failed with return code {returnCode}"); }); From 542a46b0a7675cc9b4676cdceeb1326257217261 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 15:43:48 +0900 Subject: [PATCH 099/278] Update r# version --- build/build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.cake b/build/build.cake index f1b7fa4036..de94eb7ab3 100644 --- a/build/build.cake +++ b/build/build.cake @@ -1,5 +1,5 @@ #addin "nuget:?package=CodeFileSanity&version=0.0.21" -#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.2" +#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.3.4" #tool "nuget:?package=NVika.MSBuild&version=1.0.1" var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First(); From 0cf27e244d4948d9425cdfe18941800a96d5226e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 15:44:14 +0900 Subject: [PATCH 100/278] Fix usages of SpriteText and obsolete members --- osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 66ef2a30a3..6e5104b137 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -125,13 +125,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - rankText = new SpriteText + rankText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Text = "#1", - TextSize = 30, - Font = @"Exo2.0-BoldItalic", + Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true) }, rank = new DrawableRank(ScoreRank.F) { @@ -173,8 +172,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - TextSize = 15, - Font = @"Exo2.0-Bold", + Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold) }, flag = new DrawableFlag { From d6b15f040a7b7cab448905b4b9d562105c8ff3c1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 15:57:36 +0900 Subject: [PATCH 101/278] Improve statistics display --- .../BeatmapSet/Scores/DrawableTopScore.cs | 78 ++++++++++++------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 6e5104b137..052eaf60e5 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -12,13 +12,15 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Users; using osuTK; using osuTK.Graphics; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions; +using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet.Scores @@ -26,7 +28,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class DrawableTopScore : Container { private const float fade_duration = 100; - private const float height = 100; private const float avatar_size = 80; private const float margin = 10; @@ -35,6 +36,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private Color4 backgroundIdleColour => colours.Gray3; private Color4 backgroundHoveredColour => colours.Gray4; + private readonly FontUsage smallStatisticsFont = OsuFont.GetFont(size: 20); + private readonly FontUsage largeStatisticsFont = OsuFont.GetFont(size: 25); + private readonly Box background; private readonly UpdateableAvatar avatar; private readonly DrawableFlag flag; @@ -43,14 +47,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly SpriteText date; private readonly DrawableRank rank; - private readonly SpriteText totalScoreText; - private readonly SpriteText accuracyText; - private readonly SpriteText maxComboText; - private readonly SpriteText hitGreatText; - private readonly SpriteText hitGoodText; - private readonly SpriteText hitMehText; - private readonly SpriteText hitMissText; - private readonly SpriteText ppText; + private readonly FillFlowContainer statisticsContainer; + + private readonly TextColumn totalScoreColumn; + private readonly TextColumn accuracyColumn; + private readonly TextColumn maxComboColumn; + private readonly TextColumn ppColumn; private readonly ModsInfoColumn modsInfo; @@ -71,15 +73,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores date.Text = $@"achieved {score.Date.Humanize()}"; rank.UpdateRank(score.Rank); - totalScoreText.Text = $@"{score.TotalScore:N0}"; - accuracyText.Text = $@"{score.Accuracy:P2}"; - maxComboText.Text = $@"{score.MaxCombo:N0}x"; + totalScoreColumn.Text = $@"{score.TotalScore:N0}"; + accuracyColumn.Text = $@"{score.Accuracy:P2}"; + maxComboColumn.Text = $@"{score.MaxCombo:N0}x"; + ppColumn.Text = $@"{score.PP:N0}"; - hitGreatText.Text = $"{score.Statistics[HitResult.Great]}"; - hitGoodText.Text = $"{score.Statistics[HitResult.Good]}"; - hitMehText.Text = $"{score.Statistics[HitResult.Meh]}"; - hitMissText.Text = $"{score.Statistics[HitResult.Miss]}"; - ppText.Text = $@"{score.PP:N0}"; + statisticsContainer.ChildrenEnumerable = score.Statistics.Select(kvp => new TextColumn(kvp.Key.GetDescription(), smallStatisticsFont) { Text = kvp.Value.ToString() }); modsInfo.Mods = score.Mods; } @@ -100,9 +99,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Offset = new Vector2(0, 1), }; - var smallFont = OsuFont.GetFont(size: 20); - var largeFont = OsuFont.GetFont(size: 25); - Children = new Drawable[] { background = new Box @@ -209,11 +205,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - new InfoColumn("300", hitGreatText = new OsuSpriteText { Font = smallFont }), - new InfoColumn("100", hitGoodText = new OsuSpriteText { Font = smallFont }), - new InfoColumn("50", hitMehText = new OsuSpriteText { Font = smallFont }), - new InfoColumn("misses", hitMissText = new OsuSpriteText { Font = smallFont }), - new InfoColumn("pp", ppText = new OsuSpriteText { Font = smallFont }), + statisticsContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + }, + ppColumn = new TextColumn("pp", smallStatisticsFont), modsInfo = new ModsInfoColumn(), } }, @@ -226,9 +224,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - new InfoColumn("total score", totalScoreText = new OsuSpriteText { Font = largeFont }), - new InfoColumn("accuracy", accuracyText = new OsuSpriteText { Font = largeFont }), - new InfoColumn("max combo", maxComboText = new OsuSpriteText { Font = largeFont }) + totalScoreColumn = new TextColumn("total score", largeStatisticsFont), + accuracyColumn = new TextColumn("accuracy", largeStatisticsFont), + maxComboColumn = new TextColumn("max combo", largeStatisticsFont) } }, } @@ -355,6 +353,28 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } + private class TextColumn : InfoColumn + { + private readonly SpriteText text; + + public TextColumn(string title, FontUsage font) + : this(title, new OsuSpriteText { Font = font }) + { + } + + private TextColumn(string title, SpriteText text) + : base(title, text) + { + this.text = text; + } + + public LocalisedString Text + { + get => text.Text; + set => text.Text = value; + } + } + private class ModsInfoColumn : InfoColumn { private readonly FillFlowContainer modsContainer; From 2c18b6df1c21e0983bc7536d95923a41a404ea82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 16:09:19 +0900 Subject: [PATCH 102/278] Fix score table using 300/100/50 --- .../TestCaseBeatmapScoresContainer.cs | 2 +- .../API/Requests/Responses/APILegacyScores.cs | 2 +- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 21 ++++++----- .../BeatmapSet/Scores/ScoreTableHeaderRow.cs | 22 ++++++++---- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 35 +++++-------------- .../BeatmapSet/Scores/ScoresContainer.cs | 8 ++--- 6 files changed, 41 insertions(+), 49 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs index 4a38f98810..b30d6b1546 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.SongSelect } }; - IEnumerable scores = new[] + var scores = new List { new ScoreInfo { diff --git a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs index 15ec5d3b13..c629caaa6f 100644 --- a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs +++ b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs @@ -9,6 +9,6 @@ namespace osu.Game.Online.API.Requests.Responses public class APILegacyScores { [JsonProperty(@"scores")] - public IEnumerable Scores; + public List Scores; } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 08e73da841..ada442d50e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -48,24 +48,27 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }; } - public IEnumerable Scores + public IReadOnlyList Scores { set { if (value == null || !value.Any()) return; - var content = new List { new ScoreTableHeaderRow().CreateDrawables().ToArray() }; - - int index = 0; - foreach (var s in value) - content.Add(new ScoreTableScoreRow(index++, s).CreateDrawables().ToArray()); - - scoresGrid.Content = content.ToArray(); + var content = new List + { + new ScoreTableHeaderRow(value.First()).CreateDrawables().ToArray() + }; backgroundFlow.Clear(); - for (int i = 0; i < index; i++) + + for (int i = 0; i < value.Count; i++) + { + content.Add(new ScoreTableScoreRow(i, value[i]).CreateDrawables().ToArray()); backgroundFlow.Add(new ScoreTableRowBackground(i)); + } + + scoresGrid.Content = content.ToArray(); } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs index a48716b71a..c73543eb10 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs @@ -2,15 +2,24 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Scoring; namespace osu.Game.Overlays.BeatmapSet.Scores { public class ScoreTableHeaderRow : ScoreTableRow { + private readonly ScoreInfo score; + + public ScoreTableHeaderRow(ScoreInfo score) + { + this.score = score; + } + protected override Drawable CreateIndexCell() => new CellText("rank"); protected override Drawable CreateRankCell() => new Container(); @@ -21,14 +30,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected override Drawable CreatePlayerCell() => new CellText("player"); - protected override IEnumerable CreateStatisticsCells() => new[] + protected override IEnumerable CreateStatisticsCells() { - new CellText("max combo"), - new CellText("300"), - new CellText("100"), - new CellText("50"), - new CellText("miss"), - }; + yield return new CellText("max combo"); + + foreach (var kvp in score.Statistics) + yield return new CellText(kvp.Key.GetDescription()); + } protected override Drawable CreatePpCell() => new CellText("pp"); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs index 83901cc662..2cb16a5785 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -10,7 +10,6 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Users; @@ -74,33 +73,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Font = OsuFont.GetFont(size: TEXT_SIZE) }; - yield return new OsuSpriteText + foreach (var kvp in score.Statistics) { - Text = $"{score.Statistics[HitResult.Great]}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = score.Statistics[HitResult.Great] == 0 ? Color4.Gray : Color4.White - }; - - yield return new OsuSpriteText - { - Text = $"{score.Statistics[HitResult.Good]}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = score.Statistics[HitResult.Good] == 0 ? Color4.Gray : Color4.White - }; - - yield return new OsuSpriteText - { - Text = $"{score.Statistics[HitResult.Meh]}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = score.Statistics[HitResult.Meh] == 0 ? Color4.Gray : Color4.White - }; - - yield return new OsuSpriteText - { - Text = $"{score.Statistics[HitResult.Miss]}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = score.Statistics[HitResult.Miss] == 0 ? Color4.Gray : Color4.White - }; + yield return new OsuSpriteText + { + Text = $"{kvp.Value}", + Font = OsuFont.GetFont(size: TEXT_SIZE), + Colour = kvp.Value == 0 ? Color4.Gray : Color4.White + }; + } } protected override Drawable CreatePpCell() => new OsuSpriteText diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index a29d812088..de080732f9 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -83,9 +83,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } private GetScoresRequest getScoresRequest; - private IEnumerable scores; + private IReadOnlyList scores; - public IEnumerable Scores + public IReadOnlyList Scores { get => scores; set @@ -121,11 +121,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private void updateDisplay() { - scoreTable.Scores = Enumerable.Empty(); + scoreTable.Scores = new List(); loading = false; - var scoreCount = scores?.Count() ?? 0; + var scoreCount = scores?.Count ?? 0; if (scoreCount == 0) { From e246fad301616d1b97ec20a5f21a2ef4186e731f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 16:09:34 +0900 Subject: [PATCH 103/278] Clear table if no scores are provided --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index ada442d50e..09ab0e3f6a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -52,6 +52,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { set { + scoresGrid.Content = new Drawable[0][]; + backgroundFlow.Clear(); + if (value == null || !value.Any()) return; @@ -60,8 +63,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new ScoreTableHeaderRow(value.First()).CreateDrawables().ToArray() }; - backgroundFlow.Clear(); - for (int i = 0; i < value.Count; i++) { content.Add(new ScoreTableScoreRow(i, value[i]).CreateDrawables().ToArray()); From 42c915190a968c340d6185ed10539ec2161b8c70 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 16:12:24 +0900 Subject: [PATCH 104/278] Reorder DrawableTopScore --- .../BeatmapSet/Scores/DrawableTopScore.cs | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 052eaf60e5..f22c6b3529 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -31,10 +31,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const float avatar_size = 80; private const float margin = 10; - private OsuColour colours; - - private Color4 backgroundIdleColour => colours.Gray3; - private Color4 backgroundHoveredColour => colours.Gray4; + private Color4 backgroundIdleColour; + private Color4 backgroundHoveredColour; private readonly FontUsage smallStatisticsFont = OsuFont.GetFont(size: 20); private readonly FontUsage largeStatisticsFont = OsuFont.GetFont(size: 25); @@ -56,34 +54,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly ModsInfoColumn modsInfo; - private ScoreInfo score; - - public ScoreInfo Score - { - get => score; - set - { - if (score == value) - return; - - score = value; - - avatar.User = username.User = score.User; - flag.Country = score.User.Country; - date.Text = $@"achieved {score.Date.Humanize()}"; - rank.UpdateRank(score.Rank); - - totalScoreColumn.Text = $@"{score.TotalScore:N0}"; - accuracyColumn.Text = $@"{score.Accuracy:P2}"; - maxComboColumn.Text = $@"{score.MaxCombo:N0}x"; - ppColumn.Text = $@"{score.PP:N0}"; - - statisticsContainer.ChildrenEnumerable = score.Statistics.Select(kvp => new TextColumn(kvp.Key.GetDescription(), smallStatisticsFont) { Text = kvp.Value.ToString() }); - - modsInfo.Mods = score.Mods; - } - } - public DrawableTopScore() { RelativeSizeAxes = Axes.X; @@ -240,12 +210,36 @@ namespace osu.Game.Overlays.BeatmapSet.Scores [BackgroundDependencyLoader] private void load(OsuColour colours) { - this.colours = colours; - + backgroundIdleColour = colours.Gray3; + backgroundHoveredColour = colours.Gray4; rankText.Colour = colours.Yellow; + background.Colour = backgroundIdleColour; } + /// + /// Sets the score to be displayed. + /// + public ScoreInfo Score + { + set + { + avatar.User = username.User = value.User; + flag.Country = value.User.Country; + date.Text = $@"achieved {value.Date.Humanize()}"; + rank.UpdateRank(value.Rank); + + totalScoreColumn.Text = $@"{value.TotalScore:N0}"; + accuracyColumn.Text = $@"{value.Accuracy:P2}"; + maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; + ppColumn.Text = $@"{value.PP:N0}"; + + statisticsContainer.ChildrenEnumerable = value.Statistics.Select(kvp => new TextColumn(kvp.Key.GetDescription(), smallStatisticsFont) { Text = kvp.Value.ToString() }); + + modsInfo.Mods = value.Mods; + } + } + protected override bool OnHover(HoverEvent e) { background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint); From f8596e055ad8a4c0379666a0913add225a15c456 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 16:36:38 +0900 Subject: [PATCH 105/278] Separate into multiple files --- .../TestCaseBeatmapScoresContainer.cs | 2 + .../BeatmapSet/Scores/DrawableTopScore.cs | 329 ++---------------- .../Scores/TopScoreStatisticsSection.cs | 204 +++++++++++ .../BeatmapSet/Scores/TopScoreUserSection.cs | 181 ++++++++++ 4 files changed, 409 insertions(+), 307 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs create mode 100644 osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs index b30d6b1546..0457e1469a 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs @@ -25,6 +25,8 @@ namespace osu.Game.Tests.Visual.SongSelect public override IReadOnlyList RequiredTypes => new[] { typeof(DrawableTopScore), + typeof(TopScoreUserSection), + typeof(TopScoreStatisticsSection), typeof(ScoresContainer), typeof(ScoreTable), typeof(ScoreTableRow), diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index f22c6b3529..3667fc3f9f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -1,58 +1,29 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using Humanizer; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.UI; using osu.Game.Scoring; -using osu.Game.Users; using osuTK; using osuTK.Graphics; -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Extensions; -using osu.Framework.Localisation; -using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet.Scores { public class DrawableTopScore : Container { private const float fade_duration = 100; - private const float avatar_size = 80; - private const float margin = 10; private Color4 backgroundIdleColour; private Color4 backgroundHoveredColour; - private readonly FontUsage smallStatisticsFont = OsuFont.GetFont(size: 20); - private readonly FontUsage largeStatisticsFont = OsuFont.GetFont(size: 25); - private readonly Box background; - private readonly UpdateableAvatar avatar; - private readonly DrawableFlag flag; - private readonly ClickableTopScoreUsername username; - private readonly SpriteText rankText; - private readonly SpriteText date; - private readonly DrawableRank rank; - - private readonly FillFlowContainer statisticsContainer; - - private readonly TextColumn totalScoreColumn; - private readonly TextColumn accuracyColumn; - private readonly TextColumn maxComboColumn; - private readonly TextColumn ppColumn; - - private readonly ModsInfoColumn modsInfo; + private readonly TopScoreUserSection userSection; + private readonly TopScoreStatisticsSection statisticsSection; public DrawableTopScore() { @@ -79,128 +50,30 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(margin), + Padding = new MarginPadding(10), Children = new Drawable[] { - new FillFlowContainer + new AutoSizingGrid { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), - Children = new Drawable[] - { - rankText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = "#1", - Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true) - }, - rank = new DrawableRank(ScoreRank.F) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(40), - FillMode = FillMode.Fit, - }, - avatar = new UpdateableAvatar - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(avatar_size), - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Offset = new Vector2(0, 2), - Radius = 1, - }, - }, - new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 3), - Children = new Drawable[] - { - username = new ClickableTopScoreUsername - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - }, - date = new SpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold) - }, - flag = new DrawableFlag - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(20, 13), - }, - } - } - } - }, - new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Width = 0.65f, - Child = new FillFlowContainer + Content = new[] { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Spacing = new Vector2(margin), - Children = new Drawable[] + new Drawable[] { - new FillFlowContainer + userSection = new TopScoreUserSection { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), - Children = new Drawable[] - { - statisticsContainer = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), - }, - ppColumn = new TextColumn("pp", smallStatisticsFont), - modsInfo = new ModsInfoColumn(), - } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, }, - new FillFlowContainer + statisticsSection = new TopScoreStatisticsSection { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), - Children = new Drawable[] - { - totalScoreColumn = new TextColumn("total score", largeStatisticsFont), - accuracyColumn = new TextColumn("accuracy", largeStatisticsFont), - maxComboColumn = new TextColumn("max combo", largeStatisticsFont) - } - }, - } - } + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + } + }, + }, + ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, } } } @@ -212,7 +85,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { backgroundIdleColour = colours.Gray3; backgroundHoveredColour = colours.Gray4; - rankText.Colour = colours.Yellow; background.Colour = backgroundIdleColour; } @@ -224,19 +96,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { set { - avatar.User = username.User = value.User; - flag.Country = value.User.Country; - date.Text = $@"achieved {value.Date.Humanize()}"; - rank.UpdateRank(value.Rank); - - totalScoreColumn.Text = $@"{value.TotalScore:N0}"; - accuracyColumn.Text = $@"{value.Accuracy:P2}"; - maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; - ppColumn.Text = $@"{value.PP:N0}"; - - statisticsContainer.ChildrenEnumerable = value.Statistics.Select(kvp => new TextColumn(kvp.Key.GetDescription(), smallStatisticsFont) { Text = kvp.Value.ToString() }); - - modsInfo.Mods = value.Mods; + userSection.Score = value; + statisticsSection.Score = value; } } @@ -252,157 +113,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores base.OnHoverLost(e); } - private class ClickableTopScoreUsername : ClickableUserContainer + private class AutoSizingGrid : GridContainer { - private const float username_fade_duration = 150; - - private readonly FillFlowContainer hoverContainer; - - private readonly SpriteText normalText; - private readonly SpriteText hoveredText; - - public ClickableTopScoreUsername() + public AutoSizingGrid() { - var font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true); - - Children = new Drawable[] - { - normalText = new OsuSpriteText { Font = font }, - hoverContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 1), - Children = new Drawable[] - { - hoveredText = new OsuSpriteText { Font = font }, - new Box - { - BypassAutoSizeAxes = Axes.Both, - RelativeSizeAxes = Axes.X, - Height = 1 - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverContainer.Colour = colours.Blue; - } - - protected override void OnUserChanged(User user) => normalText.Text = hoveredText.Text = user.Username; - - protected override bool OnHover(HoverEvent e) - { - hoverContainer.FadeIn(username_fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoverContainer.FadeOut(username_fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } - - private class InfoColumn : CompositeDrawable - { - private readonly Box separator; - - public InfoColumn(string title, Drawable content) - { - AutoSizeAxes = Axes.Both; - - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), - Children = new[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), - Text = title.ToUpper() - }, - separator = new Box - { - RelativeSizeAxes = Axes.X, - Height = 2 - }, - content - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - separator.Colour = colours.Gray5; - } - } - - private class TextColumn : InfoColumn - { - private readonly SpriteText text; - - public TextColumn(string title, FontUsage font) - : this(title, new OsuSpriteText { Font = font }) - { - } - - private TextColumn(string title, SpriteText text) - : base(title, text) - { - this.text = text; - } - - public LocalisedString Text - { - get => text.Text; - set => text.Text = value; - } - } - - private class ModsInfoColumn : InfoColumn - { - private readonly FillFlowContainer modsContainer; - - public ModsInfoColumn() - : this(new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal - }) - { - } - - private ModsInfoColumn(FillFlowContainer modsContainer) - : base("mods", modsContainer) - { - this.modsContainer = modsContainer; - } - - public IEnumerable Mods - { - set - { - modsContainer.Clear(); - - foreach (Mod mod in value) - { - modsContainer.Add(new ModIcon(mod) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f), - }); - } - } + AutoSizeAxes = Axes.Y; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs new file mode 100644 index 0000000000..6761d0f710 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -0,0 +1,204 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class TopScoreStatisticsSection : CompositeDrawable + { + private const float margin = 10; + + private readonly FontUsage smallFont = OsuFont.GetFont(size: 20); + private readonly FontUsage largeFont = OsuFont.GetFont(size: 25); + + private readonly TextColumn totalScoreColumn; + private readonly TextColumn accuracyColumn; + private readonly TextColumn maxComboColumn; + private readonly TextColumn ppColumn; + + private readonly FillFlowContainer statisticsColumns; + private readonly ModsInfoColumn modsColumn; + + public TopScoreStatisticsSection() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + statisticsColumns = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + }, + ppColumn = new TextColumn("pp", smallFont), + modsColumn = new ModsInfoColumn(), + } + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + totalScoreColumn = new TextColumn("total score", largeFont), + accuracyColumn = new TextColumn("accuracy", largeFont), + maxComboColumn = new TextColumn("max combo", largeFont) + } + }, + } + }; + } + + /// + /// Sets the score to be displayed. + /// + public ScoreInfo Score + { + set + { + totalScoreColumn.Text = $@"{value.TotalScore:N0}"; + accuracyColumn.Text = $@"{value.Accuracy:P2}"; + maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; + ppColumn.Text = $@"{value.PP:N0}"; + + statisticsColumns.ChildrenEnumerable = value.Statistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); + modsColumn.Mods = value.Mods; + } + } + + private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont) + { + Text = count.ToString() + }; + + private class InfoColumn : CompositeDrawable + { + private readonly Box separator; + + public InfoColumn(string title, Drawable content) + { + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new[] + { + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), + Text = title.ToUpper() + }, + separator = new Box + { + RelativeSizeAxes = Axes.X, + Height = 2 + }, + content + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + separator.Colour = colours.Gray5; + } + } + + private class TextColumn : InfoColumn + { + private readonly SpriteText text; + + public TextColumn(string title, FontUsage font) + : this(title, new OsuSpriteText { Font = font }) + { + } + + private TextColumn(string title, SpriteText text) + : base(title, text) + { + this.text = text; + } + + public LocalisedString Text + { + set => text.Text = value; + } + } + + private class ModsInfoColumn : InfoColumn + { + private readonly FillFlowContainer modsContainer; + + public ModsInfoColumn() + : this(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal + }) + { + } + + private ModsInfoColumn(FillFlowContainer modsContainer) + : base("mods", modsContainer) + { + this.modsContainer = modsContainer; + } + + public IEnumerable Mods + { + set + { + modsContainer.Clear(); + + foreach (Mod mod in value) + { + modsContainer.Add(new ModIcon(mod) + { + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f), + }); + } + } + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs new file mode 100644 index 0000000000..1ec4b7197d --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -0,0 +1,181 @@ +// 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.Allocation; +using osu.Framework.Extensions.Color4Extensions; +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.Graphics.Sprites; +using osu.Game.Online.Leaderboards; +using osu.Game.Scoring; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet.Scores +{ + public class TopScoreUserSection : CompositeDrawable + { + private readonly SpriteText rankText; + private readonly DrawableRank rank; + private readonly UpdateableAvatar avatar; + private readonly UsernameText usernameText; + private readonly SpriteText date; + private readonly DrawableFlag flag; + + public TopScoreUserSection() + { + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + rankText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "#1", + Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true) + }, + rank = new DrawableRank(ScoreRank.F) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(40), + FillMode = FillMode.Fit, + }, + avatar = new UpdateableAvatar + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(80), + Masking = true, + CornerRadius = 5, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.25f), + Offset = new Vector2(0, 2), + Radius = 1, + }, + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 3), + Children = new Drawable[] + { + usernameText = new UsernameText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + date = new SpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold) + }, + flag = new DrawableFlag + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20, 13), + }, + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + rankText.Colour = colours.Yellow; + } + + /// + /// Sets the score to be displayed. + /// + public ScoreInfo Score + { + set + { + avatar.User = usernameText.User = value.User; + flag.Country = value.User.Country; + date.Text = $@"achieved {value.Date.Humanize()}"; + rank.UpdateRank(value.Rank); + } + } + + private class UsernameText : ClickableUserContainer + { + private const float username_fade_duration = 150; + + private readonly FillFlowContainer hoverContainer; + + private readonly SpriteText normalText; + private readonly SpriteText hoveredText; + + public UsernameText() + { + var font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true); + + Children = new Drawable[] + { + normalText = new OsuSpriteText { Font = font }, + hoverContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Alpha = 0, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 1), + Children = new Drawable[] + { + hoveredText = new OsuSpriteText { Font = font }, + new Box + { + BypassAutoSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + Height = 1 + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoverContainer.Colour = colours.Blue; + } + + protected override void OnUserChanged(User user) => normalText.Text = hoveredText.Text = user.Username; + + protected override bool OnHover(HoverEvent e) + { + hoverContainer.FadeIn(username_fade_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoverContainer.FadeOut(username_fade_duration, Easing.OutQuint); + base.OnHoverLost(e); + } + } + } +} From 3da008d29380dac150b4cd1d6fb629cace86700c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 16:43:56 +0900 Subject: [PATCH 106/278] Add a bit of padding between the sections --- osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 3667fc3f9f..aace49e120 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -65,6 +65,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, + null, statisticsSection = new TopScoreStatisticsSection { Anchor = Anchor.CentreRight, @@ -72,7 +73,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } }, }, - ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize), new Dimension(GridSizeMode.Absolute, 20) }, RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, } } From 50f8ab3dfb07c9cc12b0fb5598ecadfdecf3b43d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 16:58:20 +0900 Subject: [PATCH 107/278] Fix gameplay offset handling on seeks --- .../Screens/Play/GameplayClockContainer.cs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index c13222c6de..fc7a9ddd20 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -36,6 +36,8 @@ namespace osu.Game.Screens.Play /// private readonly DecoupleableInterpolatingFramedClock adjustableClock; + private readonly double gameplayStartTime; + public readonly Bindable UserPlaybackRate = new BindableDouble(1) { Default = 1, @@ -52,11 +54,14 @@ namespace osu.Game.Screens.Play private Bindable userAudioOffset; - private readonly FramedOffsetClock offsetClock; + private readonly FramedOffsetClock userOffsetClock; + + private readonly FramedOffsetClock platformOffsetClock; public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime) { this.beatmap = beatmap; + this.gameplayStartTime = gameplayStartTime; RelativeSizeAxes = Axes.Both; @@ -64,30 +69,31 @@ namespace osu.Game.Screens.Play adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - adjustableClock.Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn)); - - adjustableClock.ProcessFrame(); - // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; // the final usable gameplay clock with user-set offsets applied. - offsetClock = new FramedOffsetClock(platformOffsetClock); + userOffsetClock = new FramedOffsetClock(platformOffsetClock); // the clock to be exposed via DI to children. - GameplayClock = new GameplayClock(offsetClock); + GameplayClock = new GameplayClock(userOffsetClock); GameplayClock.IsPaused.BindTo(IsPaused); } + private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset; + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - userAudioOffset.BindValueChanged(offset => offsetClock.Offset = offset.NewValue, true); + userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); UserPlaybackRate.ValueChanged += _ => updateRate(); + + Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn)); + adjustableClock.ProcessFrame(); } public void Restart() @@ -104,9 +110,7 @@ namespace osu.Game.Screens.Play this.Delay(750).Schedule(() => { if (!IsPaused.Value) - { - adjustableClock.Start(); - } + Start(); }); }); }); @@ -121,7 +125,12 @@ namespace osu.Game.Screens.Play IsPaused.Value = false; } - public void Seek(double time) => adjustableClock.Seek(time); + public void Seek(double time) + { + // remove the offset component here because most of the time we want the seek to be aligned to gameplay, not the audio track. + // we may want to consider reversing the application of offsets in the future as it may feel more correct. + adjustableClock.Seek(time - totalOffset); + } public void Stop() { @@ -138,7 +147,7 @@ namespace osu.Game.Screens.Play protected override void Update() { if (!IsPaused.Value) - offsetClock.ProcessFrame(); + userOffsetClock.ProcessFrame(); base.Update(); } From efd7bea7712463013746f1a9295402303d819120 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 17:01:11 +0900 Subject: [PATCH 108/278] Add further xmldoc --- osu.Game/Screens/Play/GameplayClockContainer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index fc7a9ddd20..5ded375259 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -125,6 +125,13 @@ namespace osu.Game.Screens.Play IsPaused.Value = false; } + /// + /// Seek to a specific time in gameplay. + /// + /// Adjusts for any offsets which have been applied (so the seek may not be the expected point in time on the underlying audio track). + /// + /// + /// The destination time to seek to. public void Seek(double time) { // remove the offset component here because most of the time we want the seek to be aligned to gameplay, not the audio track. From 3b7d26cca805330a1a98bb1f86059890204999dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 3 Apr 2019 17:49:01 +0900 Subject: [PATCH 109/278] Remove custom styled text --- .../Online/TestCaseBeatmapSetOverlay.cs | 1 - .../Scores/ClickableUserContainer.cs | 51 ------------- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 74 ++++++------------- .../BeatmapSet/Scores/TopScoreUserSection.cs | 73 +++--------------- 4 files changed, 31 insertions(+), 168 deletions(-) delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs index 19d295cf12..9cbccbd603 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs @@ -24,7 +24,6 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(Header), - typeof(ClickableUserContainer), typeof(ScoreTable), typeof(ScoreTableRow), typeof(ScoreTableHeaderRow), diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs deleted file mode 100644 index 2448ae17f8..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ClickableUserContainer.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; -using osu.Game.Users; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public abstract class ClickableUserContainer : Container - { - private UserProfileOverlay profile; - - protected ClickableUserContainer() - { - AutoSizeAxes = Axes.Both; - } - - [BackgroundDependencyLoader(true)] - private void load(UserProfileOverlay profile) - { - this.profile = profile; - } - - private User user; - - public User User - { - get => user; - set - { - if (user == value) - return; - - user = value; - - OnUserChanged(user); - } - } - - protected abstract void OnUserChanged(User user); - - protected override bool OnClick(ClickEvent e) - { - profile?.ShowUser(user); - return true; - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs index 2cb16a5785..adb79eedfa 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -5,10 +5,10 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.UI; using osu.Game.Scoring; @@ -53,17 +53,27 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White }; - protected override Drawable CreatePlayerCell() => new FillFlowContainer + protected override Drawable CreatePlayerCell() { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] + var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE)) { - new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) }, - new ClickableScoreUsername { User = score.User } - } - }; + AutoSizeAxes = Axes.Both, + }; + + username.AddLink(score.User.Username, null, LinkAction.OpenUserProfile, score.User.Id.ToString(), "Open profile"); + + return new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) }, + username + } + }; + } protected override IEnumerable CreateStatisticsCells() { @@ -100,47 +110,5 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Scale = new Vector2(0.3f) }) }; - - private class ClickableScoreUsername : ClickableUserContainer - { - private const int fade_duration = 100; - - private readonly SpriteText text; - private readonly SpriteText textBold; - - public ClickableScoreUsername() - { - Add(text = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TEXT_SIZE) - }); - - Add(textBold = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold), - Alpha = 0, - }); - } - - protected override void OnUserChanged(User user) => text.Text = textBold.Text = user.Username; - - protected override bool OnHover(HoverEvent e) - { - textBold.Show(); - text.Hide(); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - textBold.Hide(); - text.Show(); - base.OnHoverLost(e); - } - } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 1ec4b7197d..f401dc93a7 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -6,11 +6,11 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using osu.Game.Users; @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly SpriteText rankText; private readonly DrawableRank rank; private readonly UpdateableAvatar avatar; - private readonly UsernameText usernameText; + private readonly LinkFlowContainer usernameText; private readonly SpriteText date; private readonly DrawableFlag flag; @@ -77,10 +77,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(0, 3), Children = new Drawable[] { - usernameText = new UsernameText + usernameText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true)) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, }, date = new SpriteText { @@ -113,69 +114,15 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { set { - avatar.User = usernameText.User = value.User; + avatar.User = value.User; flag.Country = value.User.Country; date.Text = $@"achieved {value.Date.Humanize()}"; + + usernameText.Clear(); + usernameText.AddLink(value.User.Username, null, LinkAction.OpenUserProfile, value.User.Id.ToString(), "Open profile"); + rank.UpdateRank(value.Rank); } } - - private class UsernameText : ClickableUserContainer - { - private const float username_fade_duration = 150; - - private readonly FillFlowContainer hoverContainer; - - private readonly SpriteText normalText; - private readonly SpriteText hoveredText; - - public UsernameText() - { - var font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true); - - Children = new Drawable[] - { - normalText = new OsuSpriteText { Font = font }, - hoverContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 1), - Children = new Drawable[] - { - hoveredText = new OsuSpriteText { Font = font }, - new Box - { - BypassAutoSizeAxes = Axes.Both, - RelativeSizeAxes = Axes.X, - Height = 1 - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - hoverContainer.Colour = colours.Blue; - } - - protected override void OnUserChanged(User user) => normalText.Text = hoveredText.Text = user.Username; - - protected override bool OnHover(HoverEvent e) - { - hoverContainer.FadeIn(username_fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoverContainer.FadeOut(username_fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } } } From 5d37851d34b716d361cd67fa8bef60e81e36a399 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 18:14:59 +0900 Subject: [PATCH 110/278] Rename and move test to correct location --- .../TestCaseScoresContainer.cs} | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) rename osu.Game.Tests/Visual/{SongSelect/TestCaseBeatmapScoresContainer.cs => Online/TestCaseScoresContainer.cs} (96%) diff --git a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs similarity index 96% rename from osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs rename to osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs index 0457e1469a..3d87e1743c 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs @@ -15,19 +15,16 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Users; -using NUnit.Framework; -namespace osu.Game.Tests.Visual.SongSelect +namespace osu.Game.Tests.Visual.Online { - [Description("in BeatmapOverlay")] - public class TestCaseBeatmapScoresContainer : OsuTestCase + public class TestCaseScoresContainer : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(DrawableTopScore), typeof(TopScoreUserSection), typeof(TopScoreStatisticsSection), - typeof(ScoresContainer), typeof(ScoreTable), typeof(ScoreTableRow), typeof(ScoreTableHeaderRow), @@ -37,7 +34,7 @@ namespace osu.Game.Tests.Visual.SongSelect private readonly Box background; - public TestCaseBeatmapScoresContainer() + public TestCaseScoresContainer() { ScoresContainer scoresContainer; From 5c3c08566f4f99e6f414ae618a23739cd5a4df8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 18:20:03 +0900 Subject: [PATCH 111/278] DrawableTopScore can be composite --- osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index aace49e120..d8bd15a4a9 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class DrawableTopScore : Container + public class DrawableTopScore : CompositeDrawable { private const float fade_duration = 100; @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Offset = new Vector2(0, 1), }; - Children = new Drawable[] + InternalChildren = new Drawable[] { background = new Box { From a15a9bd03aa95502172ac33958c2cb36e7e5c13f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 18:29:46 +0900 Subject: [PATCH 112/278] Rewrite updateDisplay logic to not fail on some cases --- .../BeatmapSet/Scores/ScoresContainer.cs | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index de080732f9..ef2b14b8f0 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -121,25 +121,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private void updateDisplay() { - scoreTable.Scores = new List(); - loading = false; - var scoreCount = scores?.Count ?? 0; + scoreTable.Scores = scores?.Count > 1 ? scores : new List(); - if (scoreCount == 0) + if (scores.Any()) { - topScore.Hide(); - return; + topScore.Score = scores.FirstOrDefault(); + topScore.Show(); } - - topScore.Score = scores.FirstOrDefault(); - topScore.Show(); - - if (scoreCount < 2) - return; - - scoreTable.Scores = scores; + else + topScore.Hide(); } protected override void Dispose(bool isDisposing) From cb417ebd777085599a2d848e631db49b13a4c8d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 18:44:19 +0900 Subject: [PATCH 113/278] Player -> User --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs | 2 +- osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs index c73543eb10..f6f410a729 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected override Drawable CreateAccuracyCell() => new CellText("accuracy"); - protected override Drawable CreatePlayerCell() => new CellText("player"); + protected override Drawable CreateUserCell() => new CellText("player"); protected override IEnumerable CreateStatisticsCells() { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs index 8efda73270..15355512ba 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Right = 20 }, - Child = CreatePlayerCell() + Child = CreateUserCell() }; foreach (var cell in CreateStatisticsCells()) @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected abstract Drawable CreateAccuracyCell(); - protected abstract Drawable CreatePlayerCell(); + protected abstract Drawable CreateUserCell(); protected abstract IEnumerable CreateStatisticsCells(); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs index adb79eedfa..75d45d0b23 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White }; - protected override Drawable CreatePlayerCell() + protected override Drawable CreateUserCell() { var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE)) { From 84da708d44f2db71e7a50c93b5f49961787a8c3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 18:46:08 +0900 Subject: [PATCH 114/278] Fix nullref --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index ef2b14b8f0..8ef3f71fe3 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -125,7 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores scoreTable.Scores = scores?.Count > 1 ? scores : new List(); - if (scores.Any()) + if (scores?.Any() == true) { topScore.Score = scores.FirstOrDefault(); topScore.Show(); From 2ed945605ec06da3c2ff57493a83c4bc953904b3 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 3 Apr 2019 19:57:22 +0900 Subject: [PATCH 115/278] Fix Axes.None requirement for FacadeContainer --- .../Visual/TestCaseLogoFacadeContainer.cs | 292 +++++++++++------- osu.Game.Tests/Visual/TestCasePositionAxes.cs | 33 ++ .../Containers/LogoFacadeContainer.cs | 21 +- osu.Game/Screens/Menu/ButtonSystem.cs | 2 + osu.Game/Screens/Play/PlayerLoader.cs | 6 +- 5 files changed, 229 insertions(+), 125 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCasePositionAxes.cs diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index adbf22302b..b4d7976e4a 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -10,10 +11,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Screens; +using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Graphics.Containers; -using osu.Game.Screens; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; using osuTK; @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual { - public class TestCaseLogoFacadeContainer : ScreenTestCase + public class TestCaseLogoFacadeContainer : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { @@ -34,23 +34,38 @@ namespace osu.Game.Tests.Visual typeof(MainMenu) }; - [Cached] private OsuLogo logo; private readonly Bindable uiScale = new Bindable(); + private LogoFacadeContainer logoFacadeContainer; + private Container transferContainer; + private Box visualBox; + private Box transferContainerBox; + private Container logoFacade; - public TestCaseLogoFacadeContainer() - { - Add(logo = new OsuLogo()); - } + private bool randomPositions = false; [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.None }); + config.BindWith(OsuSetting.UIScale, uiScale); AddSliderStep("Adjust scale", 0.8f, 1.5f, 1f, v => uiScale.Value = v); } + [SetUpSteps] + public void SetUpSteps() + { + AddStep("Clear facades", () => + { + Clear(); + Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.None }); + logoFacadeContainer = null; + transferContainer = null; + }); + } + /// /// Move the facade to 0,0, then move it to a random new location while the logo is still transforming to it. /// Check if the logo is still tracking the facade. @@ -58,13 +73,11 @@ namespace osu.Game.Tests.Visual [Test] public void MoveFacadeTest() { - TestScreen screen = null; - bool randomPositions = false; AddToggleStep("Toggle move continuously", b => randomPositions = b); - AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen(randomPositions))); - AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); + AddStep("Add facade containers", addFacadeContainers); + AddStep("Move facade to random position", StartTrackingRandom); waitForMove(); - AddAssert("Logo is tracking", () => screen.IsLogoTracking); + AddAssert("Logo is tracking", () => IsLogoTracking); } /// @@ -73,12 +86,11 @@ namespace osu.Game.Tests.Visual [Test] public void RemoveFacadeTest() { - TestScreen screen = null; - AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen())); - AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); - AddStep("Remove facade from FacadeContainer", () => screen.RemoveFacade()); + AddStep("Add facade containers", addFacadeContainers); + AddStep("Move facade to random position", StartTrackingRandom); + AddStep("Remove facade from FacadeContainer", RemoveFacade); waitForMove(); - AddAssert("Logo is not tracking", () => !screen.IsLogoTracking); + AddAssert("Logo is not tracking", () => !IsLogoTracking); } /// @@ -87,114 +99,162 @@ namespace osu.Game.Tests.Visual [Test] public void TransferFacadeTest() { - TestScreen screen = null; - AddStep("Move facade to random position", () => LoadScreen(screen = new TestScreen())); - AddUntilStep("Screen is current", () => screen.IsCurrentScreen()); - AddStep("Remove facade from FacadeContainer", () => screen.RemoveFacade()); - AddStep("Transfer facade to a new container", () => screen.TransferFacade()); + AddStep("Add facade containers", addFacadeContainers); + AddStep("Move facade to random position", StartTrackingRandom); + AddStep("Remove facade from FacadeContainer", RemoveFacade); + AddStep("Transfer facade to a new container", TransferFacade); waitForMove(); - AddAssert("Logo is tracking", () => screen.IsLogoTracking); + AddAssert("Logo is tracking", () => IsLogoTracking); + } + + /// + /// Add a facade to a flow container then move logo to facade. + /// + [Test] + public void FlowContainerTest() + { + FillFlowContainer flowContainer; + + AddStep("Create new Logo Facade Container", () => + { + Add(logoFacadeContainer = new LogoFacadeContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Child = flowContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + } + }); + flowContainer.Children = new Drawable[] + { + new Box + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Colour = Color4.Azure, + Size = new Vector2(70) + }, + new Container + { + Alpha = 0.35f, + RelativeSizeAxes = Axes.None, + Size = new Vector2(72), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Children = new Drawable[] + { + visualBox = new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + }, + logoFacadeContainer.LogoFacade, + } + }, + new Box + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Colour = Color4.Azure, + Size = new Vector2(70) + }, + }; + }); + + AddStep("Perform logo movements", () => + { + logoFacadeContainer.Tracking = false; + logo.RelativePositionAxes = Axes.Both; + logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); + logoFacadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); + visualBox.Colour = Color4.White; + + Scheduler.AddDelayed(() => + { + logoFacadeContainer.Tracking = true; + //logo.RelativePositionAxes = Axes.None; + visualBox.Colour = Color4.Tomato; + }, 700); + }); + } + + private void addFacadeContainers() + { + AddRange(new Drawable[] + { + logoFacadeContainer = new LogoFacadeContainer + { + Alpha = 0.35f, + RelativeSizeAxes = Axes.None, + Size = new Vector2(72), + Child = visualBox = new Box + { + Colour = Color4.Tomato, + RelativeSizeAxes = Axes.Both, + } + }, + transferContainer = new Container + { + Alpha = 0.35f, + RelativeSizeAxes = Axes.None, + Size = new Vector2(72), + Child = transferContainerBox = new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + } + }, + }); + + logoFacadeContainer.Add(logoFacade = logoFacadeContainer.LogoFacade); + logoFacadeContainer.SetLogo(logo, 1.0f, 1000); } private void waitForMove() => AddWaitStep("Wait for transforms to finish", 5); - private class TestScreen : OsuScreen + private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(logoFacade.ScreenSpaceDrawQuad.Centre); + + /// + /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. + /// + public bool IsLogoTracking => Math.Abs(logo.Position.X - logoTrackingPosition.X) < 0.001f && Math.Abs(logo.Position.Y - logoTrackingPosition.Y) < 0.001f; + + public void RemoveFacade() { - private LogoFacadeContainer logoFacadeContainer; - private Container transferContainer; - private Container logoFacade; - private readonly bool randomPositions; - private OsuLogo logo; - private Box visualBox; - private Box transferContainerBox; + logoFacadeContainer.Remove(logoFacade); + visualBox.Colour = Color4.White; + moveLogoFacade(); + } - public TestScreen(bool randomPositions = false) + public void TransferFacade() + { + transferContainer.Add(logoFacade); + transferContainerBox.Colour = Color4.Tomato; + moveLogoFacade(); + } + + public void StartTrackingRandom() + { + logoFacadeContainer.Tracking = true; + moveLogoFacade(); + } + + private void moveLogoFacade() + { + Random random = new Random(); + if (logoFacade.Transforms.Count == 0 && transferContainer.Transforms.Count == 0) { - this.randomPositions = randomPositions; + logoFacadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); + transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); } - [BackgroundDependencyLoader] - private void load() - { - InternalChildren = new Drawable[] - { - logoFacadeContainer = new LogoFacadeContainer - { - Alpha = 0.35f, - RelativeSizeAxes = Axes.None, - Size = new Vector2(72), - Child = visualBox = new Box - { - Colour = Color4.Tomato, - RelativeSizeAxes = Axes.Both, - } - }, - transferContainer = new Container - { - Alpha = 0.35f, - RelativeSizeAxes = Axes.None, - Size = new Vector2(72), - Child = transferContainerBox = new Box - { - Colour = Color4.White, - RelativeSizeAxes = Axes.Both, - } - }, - }; - - logoFacadeContainer.Add(logoFacade = logoFacadeContainer.LogoFacade); - } - - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(logoFacade.ScreenSpaceDrawQuad.Centre); - - /// - /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. - /// - public bool IsLogoTracking => Math.Abs(logo.Position.X - logoTrackingPosition.X) < 0.001f && Math.Abs(logo.Position.Y - logoTrackingPosition.Y) < 0.001f; - - public void RemoveFacade() - { - logoFacadeContainer.Remove(logoFacade); - visualBox.Colour = Color4.White; - moveLogoFacade(); - } - - public void TransferFacade() - { - transferContainer.Add(logoFacade); - transferContainerBox.Colour = Color4.Tomato; - moveLogoFacade(); - } - - protected override void LogoArriving(OsuLogo logo, bool resuming) - { - base.LogoArriving(logo, resuming); - this.logo = logo; - logo.FadeIn(350); - logo.ScaleTo(new Vector2(0.15f), 350, Easing.In); - logoFacadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutQuint); - logoFacadeContainer.Tracking = true; - moveLogoFacade(); - } - - protected override void LogoExiting(OsuLogo logo) - { - base.LogoExiting(logo); - logoFacadeContainer.Tracking = false; - } - - private void moveLogoFacade() - { - Random random = new Random(); - if (logoFacade.Transforms.Count == 0 && transferContainer.Transforms.Count == 0) - { - logoFacadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); - transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)DrawWidth), random.Next(0, (int)DrawHeight)), 300); - } - - if (randomPositions) - Schedule(moveLogoFacade); - } + if (randomPositions) + Schedule(moveLogoFacade); } } } diff --git a/osu.Game.Tests/Visual/TestCasePositionAxes.cs b/osu.Game.Tests/Visual/TestCasePositionAxes.cs new file mode 100644 index 0000000000..04ff0dcf8c --- /dev/null +++ b/osu.Game.Tests/Visual/TestCasePositionAxes.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osuTK; + +namespace osu.Game.Tests.Visual +{ + public class TestCasePositionAxes : OsuTestCase + { + private Box box; + + public TestCasePositionAxes() + { + Add(new Container() + { + Size = new Vector2(1), + Child = box = new Box + { + Size = new Vector2(25), + RelativePositionAxes = Axes.None, + Position = new Vector2(250) + } + }); + + AddStep("blank", () => { }); + AddStep("change axes", () => box.RelativePositionAxes = Axes.Both); + } + } +} diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index 547af87522..c9f41e75e7 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Graphics.Containers /// The scale of the facade. Does not actually affect the logo itself. /// The duration of the initial transform. Default is instant. /// The easing type of the initial transform. - public void SetLogo(OsuLogo logo, float facadeScale, double duration = 0, Easing easing = Easing.None) + public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) { this.logo = logo ?? throw new ArgumentNullException(nameof(logo)); this.facadeScale = facadeScale; @@ -54,11 +54,19 @@ namespace osu.Game.Graphics.Containers startPosition = null; } - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre); - - protected override void UpdateAfterChildren() + private Vector2 localSpaceConversion() { - base.UpdateAfterChildren(); + Vector2 local; + local.X = logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / logo.Parent.RelativeToAbsoluteFactor.X; + local.Y = logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / logo.Parent.RelativeToAbsoluteFactor.Y; + return local; + } + + private Vector2 logoTrackingPosition => logo.RelativePositionAxes == Axes.None ? logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre) : localSpaceConversion(); + + protected override void Update() + { + base.Update(); if (logo == null || !Tracking) return; @@ -68,9 +76,6 @@ namespace osu.Game.Graphics.Containers if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition) { - // Required for the correct position of the logo to be set with respect to logoTrackingPosition - logo.RelativePositionAxes = Axes.None; - // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == null || startPosition == null) { diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f13dadf3dd..607700649d 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -290,6 +290,7 @@ namespace osu.Game.Screens.Menu break; case ButtonSystemState.Initial: logo.ClearTransforms(targetMember: nameof(Position)); + logo.RelativePositionAxes = Axes.None; bool impact = logo.Scale.X > 0.6f; @@ -310,6 +311,7 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); + logo.RelativePositionAxes = Axes.None; logoFacadeContainer.Tracking = true; logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 9e6f7cf24e..19607129a0 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -172,7 +172,11 @@ namespace osu.Game.Screens.Play content.SetLogo(logo, 1.0f, 500, Easing.InOutExpo); - Scheduler.AddDelayed(() => content.Tracking = true, resuming ? 0 : 500); + Scheduler.AddDelayed(() => + { + content.Tracking = true; + //logo.RelativePositionAxes = Axes.None; + }, resuming ? 0 : 500); } protected override void LogoExiting(OsuLogo logo) From 8a40b27e8fc3cf9b17069439e8af130a72d7564e Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 3 Apr 2019 20:32:53 +0900 Subject: [PATCH 116/278] Remove need for logo relativePositionAxes none --- osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs | 1 - osu.Game/Graphics/Containers/LogoFacadeContainer.cs | 10 ++++------ osu.Game/Screens/Menu/ButtonSystem.cs | 2 -- osu.Game/Screens/Play/PlayerLoader.cs | 1 - 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index b4d7976e4a..bd1fb932bb 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -177,7 +177,6 @@ namespace osu.Game.Tests.Visual Scheduler.AddDelayed(() => { logoFacadeContainer.Tracking = true; - //logo.RelativePositionAxes = Axes.None; visualBox.Colour = Color4.Tomato; }, 700); }); diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index c9f41e75e7..76903a20b3 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -54,7 +54,7 @@ namespace osu.Game.Graphics.Containers startPosition = null; } - private Vector2 localSpaceConversion() + private Vector2 logoTrackingPosition() { Vector2 local; local.X = logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / logo.Parent.RelativeToAbsoluteFactor.X; @@ -62,8 +62,6 @@ namespace osu.Game.Graphics.Containers return local; } - private Vector2 logoTrackingPosition => logo.RelativePositionAxes == Axes.None ? logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre) : localSpaceConversion(); - protected override void Update() { base.Update(); @@ -74,7 +72,7 @@ namespace osu.Game.Graphics.Containers // Account for the scale of the actual logo container, as SizeForFlow only accounts for the sprite scale. LogoFacade.Size = new Vector2(logo.SizeForFlow * logo.Scale.X * facadeScale); - if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition) + if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition()) { // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == null || startPosition == null) @@ -90,11 +88,11 @@ namespace osu.Game.Graphics.Containers var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); // Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location. - logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), logoTrackingPosition, mount); + logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), logoTrackingPosition(), mount); } else { - logo.Position = logoTrackingPosition; + logo.Position = logoTrackingPosition(); } } } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 607700649d..f13dadf3dd 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -290,7 +290,6 @@ namespace osu.Game.Screens.Menu break; case ButtonSystemState.Initial: logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.None; bool impact = logo.Scale.X > 0.6f; @@ -311,7 +310,6 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.None; logoFacadeContainer.Tracking = true; logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 19607129a0..2ba5bd81d1 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -175,7 +175,6 @@ namespace osu.Game.Screens.Play Scheduler.AddDelayed(() => { content.Tracking = true; - //logo.RelativePositionAxes = Axes.None; }, resuming ? 0 : 500); } From 73c7c6c31613175bcdcfe30d4169bdd160e2b52b Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Wed, 3 Apr 2019 21:44:36 +0800 Subject: [PATCH 117/278] Hides "Details" button when OnlineBeatmapID is null --- .../Carousel/DrawableCarouselBeatmap.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 38ca9a9aed..a31e40dd8f 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -2,6 +2,7 @@ // 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.Colour; @@ -167,16 +168,21 @@ namespace osu.Game.Screens.Select.Carousel base.ApplyState(); } - - public MenuItem[] ContextMenuItems => new MenuItem[] + public MenuItem[] ContextMenuItems { - new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap)), - new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)), - new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap)), - new OsuMenuItem("Details", MenuItemType.Standard, () => + get { - if (beatmap.OnlineBeatmapID.HasValue) beatmapOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value); - }), - }; + List items = new List(); + + items.Add(new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap))); + items.Add(new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap))); + items.Add(new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap))); + + if (beatmap.OnlineBeatmapID.HasValue) + items.Add(new OsuMenuItem("Details", MenuItemType.Standard, () => beatmapOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value))); + + return items.ToArray(); + } + } } } From 55a6e43778da2a932f1b7ae41e713107c7fae54e Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Wed, 3 Apr 2019 21:49:33 +0800 Subject: [PATCH 118/278] Check against databasedSet instead of function param --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9ab09d1122..b31b9e5e87 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -255,7 +255,7 @@ namespace osu.Game menuScreen.LoadToSolo(); // we might even already be at the song - if (Beatmap.Value.BeatmapSetInfo.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) + if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash) { return; } From 4d60f6fb6a0cd17fb4e330a4f67177bab083d4e8 Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Wed, 3 Apr 2019 22:37:50 +0800 Subject: [PATCH 119/278] Use collection initializer and added missing blank line --- .../Select/Carousel/DrawableCarouselBeatmap.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index a31e40dd8f..0b60ca03a7 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -168,16 +168,18 @@ namespace osu.Game.Screens.Select.Carousel base.ApplyState(); } + public MenuItem[] ContextMenuItems { get { - List items = new List(); - - items.Add(new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap))); - items.Add(new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap))); - items.Add(new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap))); - + List items = new List() + { + new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap)), + new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)), + new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap)), + }; + if (beatmap.OnlineBeatmapID.HasValue) items.Add(new OsuMenuItem("Details", MenuItemType.Standard, () => beatmapOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value))); From 36609244410b25aa4f42596d126d3a66651998e3 Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Wed, 3 Apr 2019 22:40:20 +0800 Subject: [PATCH 120/278] Trimmed whitespace --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 0b60ca03a7..c19fa73ab1 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Select.Carousel new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)), new OsuMenuItem("Hide", MenuItemType.Destructive, () => hideRequested?.Invoke(beatmap)), }; - + if (beatmap.OnlineBeatmapID.HasValue) items.Add(new OsuMenuItem("Details", MenuItemType.Standard, () => beatmapOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value))); From bb516da5b6903c454c5b9197e57ab4db72b39a23 Mon Sep 17 00:00:00 2001 From: Samuel Van Allen Date: Wed, 3 Apr 2019 22:57:05 +0800 Subject: [PATCH 121/278] Removed redundant empty argument list --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index c19fa73ab1..0a20f2aa6d 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Select.Carousel { get { - List items = new List() + List items = new List { new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested?.Invoke(beatmap)), new OsuMenuItem("Edit", MenuItemType.Standard, () => editRequested?.Invoke(beatmap)), From ccc804a9b2ac61e4f90448fd265dac4ec1db568f Mon Sep 17 00:00:00 2001 From: jorolf Date: Thu, 4 Apr 2019 00:24:42 +0200 Subject: [PATCH 122/278] get everything working again --- .../{ => Online}/TestCaseUserProfileHeader.cs | 4 +-- .../Graphics/UserInterface/ScreenTitle.cs | 6 +++-- .../Profile/Header/BottomHeaderContainer.cs | 18 ++++++------- .../Profile/Header/CenterHeaderContainer.cs | 6 ++--- .../Profile/Header/ProfileMessageButton.cs | 8 +++--- .../Overlays/Profile/Header/SupporterIcon.cs | 5 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 27 +++++++++++++------ osu.Game/Screens/Multi/Header.cs | 2 +- osu.Game/Users/UserCoverBackground.cs | 7 ++--- osu.Game/Users/UserPanel.cs | 2 +- 10 files changed, 49 insertions(+), 36 deletions(-) rename osu.Game.Tests/Visual/{ => Online}/TestCaseUserProfileHeader.cs (96%) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs similarity index 96% rename from osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs rename to osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index 8f36b4dda8..98bad9831f 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; -namespace osu.Game.Tests.Visual +namespace osu.Game.Tests.Visual.Online { public class TestCaseUserProfileHeader : OsuTestCase { @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual }; [Resolved] - private APIAccess api { get; set; } + private IAPIProvider api { get; set; } private readonly ProfileHeader header; diff --git a/osu.Game/Graphics/UserInterface/ScreenTitle.cs b/osu.Game/Graphics/UserInterface/ScreenTitle.cs index 1574023068..b9d9b5427d 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitle.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitle.cs @@ -14,6 +14,8 @@ namespace osu.Game.Graphics.UserInterface { private readonly SpriteIcon iconSprite; private readonly OsuSpriteText titleText, pageText; + public const float ICON_WIDTH = icon_size + icon_spacing; + private const float icon_size = 25, icon_spacing = 10; protected IconUsage Icon { @@ -48,12 +50,12 @@ namespace osu.Game.Graphics.UserInterface new FillFlowContainer { AutoSizeAxes = Axes.Both, - Spacing = new Vector2(10, 0), + Spacing = new Vector2(icon_spacing, 0), Children = new Drawable[] { iconSprite = new SpriteIcon { - Size = new Vector2(25), + Size = new Vector2(icon_size), }, new FillFlowContainer { diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 1f9d741b8d..04b70ea10f 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.Profile.Header bottomTopLinkContainer.AddText("Contributed "); bottomTopLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); - void tryAddInfo(FontAwesome icon, string content, string link = null) + void tryAddInfo(IconUsage icon, string content, string link = null) { if (string.IsNullOrEmpty(content)) return; @@ -138,16 +138,16 @@ namespace osu.Game.Overlays.Profile.Header websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); } - tryAddInfo(FontAwesome.fa_map_marker, user.Location); - tryAddInfo(FontAwesome.fa_heart_o, user.Interests); - tryAddInfo(FontAwesome.fa_suitcase, user.Occupation); + tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); + tryAddInfo(OsuIcon.Heart, user.Interests); + tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation); bottomLinkContainer.NewLine(); if (!string.IsNullOrEmpty(user.Twitter)) - tryAddInfo(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfo(FontAwesome.fa_gamepad, user.Discord); //todo: update fontawesome to include discord logo - tryAddInfo(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); - tryAddInfo(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfo(FontAwesome.fa_link, websiteWithoutProtcol, user.Website); + tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); + tryAddInfo(FontAwesome.Brands.Discord, user.Discord); + tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtcol, user.Website); } } } diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs index b5e04bee9e..3d0b9b9db4 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_user, + Icon = FontAwesome.Solid.User, FillMode = FillMode.Fit, Size = new Vector2(50, 14) }, @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(20), - Icon = FontAwesome.fa_chevron_up, + Icon = FontAwesome.Solid.ChevronUp, }, } }, @@ -212,7 +212,7 @@ namespace osu.Game.Overlays.Profile.Header detailsToggleButton.Action = () => { detailsVisible = !detailsVisible; - expandButtonIcon.Icon = detailsVisible ? FontAwesome.fa_chevron_down : FontAwesome.fa_chevron_up; + expandButtonIcon.Icon = detailsVisible ? FontAwesome.Solid.ChevronDown : FontAwesome.Solid.ChevronUp; hiddenDetailContainer.Alpha = detailsVisible ? 1 : 0; expandedDetailContainer.Alpha = detailsVisible ? 0 : 1; DetailsVisibilityAction(detailsVisible); diff --git a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs index a14c0324d7..3121eae727 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs @@ -4,7 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Game.Graphics; +using osu.Framework.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Online.Chat; using osu.Game.Users; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header private ChatOverlay chatOverlay { get; set; } [Resolved] - private APIAccess apiAccess { get; set; } + private IAPIProvider apiProvider { get; set; } public ProfileMessageButton() { @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_envelope, + Icon = FontAwesome.Solid.Envelope, FillMode = FillMode.Fit, Size = new Vector2(50, 14) }; @@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Header chatOverlay?.Show(); }; - User.ValueChanged += e => Content.Alpha = !e.NewValue.PMFriendsOnly && apiAccess.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; + User.ValueChanged += e => Content.Alpha = !e.NewValue.PMFriendsOnly && apiProvider.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; } } } diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs index 3cb30ab044..569ed252b7 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Header { Width = 12, RelativeSizeAxes = Axes.Y, - Icon = FontAwesome.fa_heart, + Icon = FontAwesome.Solid.Heart, }); } @@ -66,8 +66,7 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.X, Height = 0.6f, Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.Solid.Heart, + Origin = Anchor.Centre } } }; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 988fa3afd9..b75de39c4b 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -5,11 +5,11 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; using osu.Framework.Bindables; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Profile @@ -17,7 +17,6 @@ namespace osu.Game.Overlays.Profile public class ProfileHeader : Container { private readonly UserCoverBackground coverContainer; - private readonly ScreenTitle coverTitle; private readonly ProfileHeaderTabControl infoTabControl; private const float cover_height = 150; @@ -52,10 +51,9 @@ namespace osu.Game.Overlays.Profile Depth = -float.MaxValue, Children = new Drawable[] { - coverTitle = new ScreenTitle + new ProfileHeaderTitle { - Title = "Player ", - Page = "Info" + X = -ScreenTitle.ICON_WIDTH, }, infoTabControl = new ProfileHeaderTabControl { @@ -113,10 +111,8 @@ namespace osu.Game.Overlays.Profile } [BackgroundDependencyLoader] - private void load(OsuColour colours, TextureStore textures) + private void load(OsuColour colours) { - coverTitle.AccentColour = colours.CommunityUserGreen; - infoTabControl.AccentColour = colours.CommunityUserGreen; } @@ -131,5 +127,20 @@ namespace osu.Game.Overlays.Profile { public string TooltipText { get; set; } } + + private class ProfileHeaderTitle : ScreenTitle + { + public ProfileHeaderTitle() + { + Title = "Player "; + Section = "Info"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.CommunityUserGreen; + } + } } } diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 7924086389..35edc5bac8 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Multi { Anchor = Anchor.CentreLeft, Origin = Anchor.BottomLeft, - X = -35, + X = -ScreenTitle.ICON_WIDTH, }, breadcrumbs = new HeaderBreadcrumbControl(stack) { diff --git a/osu.Game/Users/UserCoverBackground.cs b/osu.Game/Users/UserCoverBackground.cs index d037f809b4..dbc132995a 100644 --- a/osu.Game/Users/UserCoverBackground.cs +++ b/osu.Game/Users/UserCoverBackground.cs @@ -36,15 +36,16 @@ namespace osu.Game.Users } else { - return new Sprite + var sprite = new Sprite { RelativeSizeAxes = Axes.Both, Texture = textures.Get(user.CoverUrl), FillMode = FillMode.Fill, Anchor = Anchor.Centre, - Origin = Anchor.Centre, - OnLoadComplete = d => d.FadeInFromZero(400), + Origin = Anchor.Centre }; + sprite.OnLoadComplete += d => d.FadeInFromZero(400); + return sprite; } } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 0e928e0aac..eb7f0941fb 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -76,7 +76,7 @@ namespace osu.Game.Users Children = new Drawable[] { - new DelayedLoadWrapper(coverBackground = new UserCoverBackground(user) + new DelayedLoadWrapper(coverBackground = new UserCoverBackground { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, From ba871364514ae468bc5e0a47a12c4adda5206dc0 Mon Sep 17 00:00:00 2001 From: jorolf Date: Thu, 4 Apr 2019 00:57:15 +0200 Subject: [PATCH 123/278] add gradient and fix remaining error --- .../Visual/Online/TestCaseUserProfile.cs | 10 +++------- osu.Game/Overlays/Profile/ProfileHeader.cs | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs index abb96b8e84..c455c092ed 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs @@ -20,7 +20,9 @@ namespace osu.Game.Tests.Visual.Online public class TestCaseUserProfile : OsuTestCase { private readonly TestUserProfileOverlay profile; - private IAPIProvider api; + + [Resolved] + private IAPIProvider api { get; set; } public override IReadOnlyList RequiredTypes => new[] { @@ -75,12 +77,6 @@ namespace osu.Game.Tests.Visual.Online Add(profile = new TestUserProfileOverlay()); } - [BackgroundDependencyLoader] - private void load(APIAccess api) - { - this.api = api; - } - protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index b75de39c4b..776fcbb8b7 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -9,6 +9,9 @@ using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -35,10 +38,23 @@ namespace osu.Game.Overlays.Profile Children = new Drawable[] { - coverContainer = new UserCoverBackground + new Container { RelativeSizeAxes = Axes.X, Height = cover_height, + Masking = true, + Children = new Drawable[] + { + coverContainer = new UserCoverBackground + { + RelativeSizeAxes = Axes.Both, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(OsuColour.FromHex("222").Opacity(0.8f), OsuColour.FromHex("222").Opacity(0.2f)) + }, + } }, new Container { From 6b5458a625840759eb178278a88f423532359081 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 11:22:05 +0900 Subject: [PATCH 124/278] Clean up test cases --- .../Visual/TestCaseLogoFacadeContainer.cs | 92 +++++++++---------- osu.Game.Tests/Visual/TestCasePositionAxes.cs | 33 ------- .../Containers/LogoFacadeContainer.cs | 23 ++--- 3 files changed, 57 insertions(+), 91 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCasePositionAxes.cs diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index bd1fb932bb..d66ac19aed 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Drawing; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -35,21 +34,18 @@ namespace osu.Game.Tests.Visual }; private OsuLogo logo; - private readonly Bindable uiScale = new Bindable(); - private LogoFacadeContainer logoFacadeContainer; + private TestLogoFacadeContainer facadeContainer; private Container transferContainer; private Box visualBox; private Box transferContainerBox; private Container logoFacade; - private bool randomPositions = false; + private bool randomPositions; [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.None }); - config.BindWith(OsuSetting.UIScale, uiScale); AddSliderStep("Adjust scale", 0.8f, 1.5f, 1f, v => uiScale.Value = v); } @@ -60,8 +56,8 @@ namespace osu.Game.Tests.Visual AddStep("Clear facades", () => { Clear(); - Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.None }); - logoFacadeContainer = null; + Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.Both }); + facadeContainer = null; transferContainer = null; }); } @@ -75,9 +71,9 @@ namespace osu.Game.Tests.Visual { AddToggleStep("Toggle move continuously", b => randomPositions = b); AddStep("Add facade containers", addFacadeContainers); - AddStep("Move facade to random position", StartTrackingRandom); + AddStep("Move facade to random position", startTrackingRandom); waitForMove(); - AddAssert("Logo is tracking", () => IsLogoTracking); + AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); } /// @@ -87,10 +83,10 @@ namespace osu.Game.Tests.Visual public void RemoveFacadeTest() { AddStep("Add facade containers", addFacadeContainers); - AddStep("Move facade to random position", StartTrackingRandom); - AddStep("Remove facade from FacadeContainer", RemoveFacade); + AddStep("Move facade to random position", startTrackingRandom); + AddStep("Remove facade from FacadeContainer", removeFacade); waitForMove(); - AddAssert("Logo is not tracking", () => !IsLogoTracking); + AddAssert("Logo is not tracking", () => !facadeContainer.IsLogoTracking); } /// @@ -100,11 +96,16 @@ namespace osu.Game.Tests.Visual public void TransferFacadeTest() { AddStep("Add facade containers", addFacadeContainers); - AddStep("Move facade to random position", StartTrackingRandom); - AddStep("Remove facade from FacadeContainer", RemoveFacade); - AddStep("Transfer facade to a new container", TransferFacade); + AddStep("Move facade to random position", startTrackingRandom); + AddStep("Remove facade from FacadeContainer", removeFacade); + AddStep("Transfer facade to a new container", () => + { + transferContainer.Add(logoFacade); + transferContainerBox.Colour = Color4.Tomato; + moveLogoFacade(); + }); waitForMove(); - AddAssert("Logo is tracking", () => IsLogoTracking); + AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); } /// @@ -115,9 +116,9 @@ namespace osu.Game.Tests.Visual { FillFlowContainer flowContainer; - AddStep("Create new Logo Facade Container", () => + AddStep("Create new flow container with facade", () => { - Add(logoFacadeContainer = new LogoFacadeContainer + Add(facadeContainer = new TestLogoFacadeContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopCentre, @@ -153,7 +154,7 @@ namespace osu.Game.Tests.Visual Colour = Color4.White, RelativeSizeAxes = Axes.Both, }, - logoFacadeContainer.LogoFacade, + facadeContainer.LogoFacade, } }, new Box @@ -168,25 +169,28 @@ namespace osu.Game.Tests.Visual AddStep("Perform logo movements", () => { - logoFacadeContainer.Tracking = false; + facadeContainer.Tracking = false; logo.RelativePositionAxes = Axes.Both; logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); - logoFacadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); + facadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); visualBox.Colour = Color4.White; Scheduler.AddDelayed(() => { - logoFacadeContainer.Tracking = true; + facadeContainer.Tracking = true; visualBox.Colour = Color4.Tomato; }, 700); }); + + waitForMove(); + AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); } private void addFacadeContainers() { AddRange(new Drawable[] { - logoFacadeContainer = new LogoFacadeContainer + facadeContainer = new TestLogoFacadeContainer { Alpha = 0.35f, RelativeSizeAxes = Axes.None, @@ -210,50 +214,44 @@ namespace osu.Game.Tests.Visual }, }); - logoFacadeContainer.Add(logoFacade = logoFacadeContainer.LogoFacade); - logoFacadeContainer.SetLogo(logo, 1.0f, 1000); + facadeContainer.Add(logoFacade = facadeContainer.LogoFacade); + facadeContainer.SetLogo(logo, 1.0f, 1000); } private void waitForMove() => AddWaitStep("Wait for transforms to finish", 5); - private Vector2 logoTrackingPosition => logo.Parent.ToLocalSpace(logoFacade.ScreenSpaceDrawQuad.Centre); - - /// - /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. - /// - public bool IsLogoTracking => Math.Abs(logo.Position.X - logoTrackingPosition.X) < 0.001f && Math.Abs(logo.Position.Y - logoTrackingPosition.Y) < 0.001f; - - public void RemoveFacade() + private void removeFacade() { - logoFacadeContainer.Remove(logoFacade); + facadeContainer.Remove(logoFacade); visualBox.Colour = Color4.White; moveLogoFacade(); } - public void TransferFacade() + private void startTrackingRandom() { - transferContainer.Add(logoFacade); - transferContainerBox.Colour = Color4.Tomato; - moveLogoFacade(); - } - - public void StartTrackingRandom() - { - logoFacadeContainer.Tracking = true; + facadeContainer.Tracking = true; moveLogoFacade(); } private void moveLogoFacade() { - Random random = new Random(); - if (logoFacade.Transforms.Count == 0 && transferContainer.Transforms.Count == 0) + if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) { - logoFacadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); + Random random = new Random(); + facadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); } if (randomPositions) Schedule(moveLogoFacade); } + + private class TestLogoFacadeContainer : LogoFacadeContainer + { + /// + /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. + /// + public bool IsLogoTracking => Math.Abs(Logo.Position.X - LogoTrackingPosition().X) < 0.001f && Math.Abs(Logo.Position.Y - LogoTrackingPosition().Y) < 0.001f; + } } } diff --git a/osu.Game.Tests/Visual/TestCasePositionAxes.cs b/osu.Game.Tests/Visual/TestCasePositionAxes.cs deleted file mode 100644 index 04ff0dcf8c..0000000000 --- a/osu.Game.Tests/Visual/TestCasePositionAxes.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; -using osuTK; - -namespace osu.Game.Tests.Visual -{ - public class TestCasePositionAxes : OsuTestCase - { - private Box box; - - public TestCasePositionAxes() - { - Add(new Container() - { - Size = new Vector2(1), - Child = box = new Box - { - Size = new Vector2(25), - RelativePositionAxes = Axes.None, - Position = new Vector2(250) - } - }); - - AddStep("blank", () => { }); - AddStep("change axes", () => box.RelativePositionAxes = Axes.Both); - } - } -} diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index 76903a20b3..a80b687057 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -24,7 +24,8 @@ namespace osu.Game.Graphics.Containers /// public bool Tracking = false; - private OsuLogo logo; + protected OsuLogo Logo; + private float facadeScale; private Easing easing; private Vector2? startPosition; @@ -45,7 +46,7 @@ namespace osu.Game.Graphics.Containers /// The easing type of the initial transform. public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) { - this.logo = logo ?? throw new ArgumentNullException(nameof(logo)); + Logo = logo ?? throw new ArgumentNullException(nameof(logo)); this.facadeScale = facadeScale; this.duration = duration; this.easing = easing; @@ -54,11 +55,11 @@ namespace osu.Game.Graphics.Containers startPosition = null; } - private Vector2 logoTrackingPosition() + protected Vector2 LogoTrackingPosition() { Vector2 local; - local.X = logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / logo.Parent.RelativeToAbsoluteFactor.X; - local.Y = logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / logo.Parent.RelativeToAbsoluteFactor.Y; + local.X = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X; + local.Y = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y; return local; } @@ -66,19 +67,19 @@ namespace osu.Game.Graphics.Containers { base.Update(); - if (logo == null || !Tracking) + if (Logo == null || !Tracking) return; // Account for the scale of the actual logo container, as SizeForFlow only accounts for the sprite scale. - LogoFacade.Size = new Vector2(logo.SizeForFlow * logo.Scale.X * facadeScale); + LogoFacade.Size = new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale); - if (LogoFacade.Parent != null && logo.Position != logoTrackingPosition()) + if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition()) { // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == null || startPosition == null) { startTime = Time.Current; - startPosition = logo.Position; + startPosition = Logo.Position; } if (duration != 0) @@ -88,11 +89,11 @@ namespace osu.Game.Graphics.Containers var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); // Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location. - logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), logoTrackingPosition(), mount); + Logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), LogoTrackingPosition(), mount); } else { - logo.Position = logoTrackingPosition(); + Logo.Position = LogoTrackingPosition(); } } } From 15b2b6af7d8c8da6c371b14ff4c571b1c284d423 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 11:28:36 +0900 Subject: [PATCH 125/278] Clean up remaining assignments of logo relativePositionAxes --- osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs | 1 - osu.Game/Screens/Menu/ButtonSystem.cs | 2 -- osu.Game/Screens/Play/PlayerLoader.cs | 5 +---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs index d66ac19aed..3e9d52483d 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs @@ -170,7 +170,6 @@ namespace osu.Game.Tests.Visual AddStep("Perform logo movements", () => { facadeContainer.Tracking = false; - logo.RelativePositionAxes = Axes.Both; logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); facadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); visualBox.Colour = Color4.White; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f13dadf3dd..cb95ec1765 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -276,8 +276,6 @@ namespace osu.Game.Screens.Menu game?.Toolbar.Hide(); logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.Both; - logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); logo.ScaleTo(1, 800, Easing.OutExpo); }, buttonArea.Alpha * 150); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 2ba5bd81d1..ba27f87ee6 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -131,12 +131,9 @@ namespace osu.Game.Screens.Play private void contentOut() { - // Ensure the logo is no longer tracking before we scale the content, and that its RelativePositionAxes have been returned. + // Ensure the logo is no longer tracking before we scale the content content.Tracking = false; - if (logo != null) - logo.RelativePositionAxes = Axes.Both; - content.ScaleTo(0.7f, 300, Easing.InQuint); content.FadeOut(250); } From e89143d76b94610bf88c3a733e64e340f97713e5 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 12:07:11 +0900 Subject: [PATCH 126/278] Add xmldoc for LogoTrackingPosition --- osu.Game/Graphics/Containers/LogoFacadeContainer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index a80b687057..1664fdde4d 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -55,6 +55,12 @@ namespace osu.Game.Graphics.Containers startPosition = null; } + /// + /// Gets the position that the logo should move to with respect to the . + /// Manually performs a conversion of the Facade's position to the relative position of the Logo's Parent. + /// + /// Will only be correct if the logo's are set to Axes.Both + /// The position that the logo should move to in its parent's relative space. protected Vector2 LogoTrackingPosition() { Vector2 local; From b2857384b8f3c83be474b17cca9c7cc90342cf4e Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 12:08:05 +0900 Subject: [PATCH 127/278] Remove unnecessary logo assignment --- osu.Game/Screens/Play/PlayerLoader.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index ba27f87ee6..ccfd965f53 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -37,8 +37,6 @@ namespace osu.Game.Screens.Play private BeatmapMetadataDisplay info; - private OsuLogo logo; - private bool hideOverlays; public override bool HideOverlaysOnEnter => hideOverlays; @@ -155,8 +153,6 @@ namespace osu.Game.Screens.Play { base.LogoArriving(logo, resuming); - this.logo = logo; - const double duration = 300; if (!resuming) From f2bbde83bf3788957ffb3ad7b7e35b1f2e4c9e6d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 13:05:34 +0900 Subject: [PATCH 128/278] Use precision almost equals --- .../{ => UserInterface}/TestCaseLogoFacadeContainer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename osu.Game.Tests/Visual/{ => UserInterface}/TestCaseLogoFacadeContainer.cs (97%) diff --git a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs similarity index 97% rename from osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs rename to osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs index 3e9d52483d..4bc4ae724a 100644 --- a/osu.Game.Tests/Visual/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; +using osu.Framework.MathUtils; using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Graphics.Containers; @@ -18,7 +19,7 @@ using osu.Game.Screens.Play; using osuTK; using osuTK.Graphics; -namespace osu.Game.Tests.Visual +namespace osu.Game.Tests.Visual.UserInterface { public class TestCaseLogoFacadeContainer : OsuTestCase { @@ -250,7 +251,7 @@ namespace osu.Game.Tests.Visual /// /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. /// - public bool IsLogoTracking => Math.Abs(Logo.Position.X - LogoTrackingPosition().X) < 0.001f && Math.Abs(Logo.Position.Y - LogoTrackingPosition().Y) < 0.001f; + public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition()); } } } From b2e932dc74c5eae1184172758b3a62789d23e719 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 13:13:03 +0900 Subject: [PATCH 129/278] Clean up tests, xmldoc --- .../UserInterface/TestCaseLogoFacadeContainer.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs index 4bc4ae724a..5f864eeabb 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs @@ -41,9 +41,10 @@ namespace osu.Game.Tests.Visual.UserInterface private Box visualBox; private Box transferContainerBox; private Container logoFacade; - private bool randomPositions; + private const float visual_box_size = 72; + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { @@ -110,7 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface } /// - /// Add a facade to a flow container then move logo to facade. + /// Add a facade to a flow container, move the logo to the center of the screen, then start tracking on the facade. /// [Test] public void FlowContainerTest() @@ -139,13 +140,13 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Colour = Color4.Azure, - Size = new Vector2(70) + Size = new Vector2(visual_box_size) }, new Container { Alpha = 0.35f, RelativeSizeAxes = Axes.None, - Size = new Vector2(72), + Size = new Vector2(visual_box_size), Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Children = new Drawable[] @@ -163,7 +164,7 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Colour = Color4.Azure, - Size = new Vector2(70) + Size = new Vector2(visual_box_size) }, }; }); @@ -194,7 +195,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Alpha = 0.35f, RelativeSizeAxes = Axes.None, - Size = new Vector2(72), + Size = new Vector2(visual_box_size), Child = visualBox = new Box { Colour = Color4.Tomato, @@ -205,7 +206,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Alpha = 0.35f, RelativeSizeAxes = Axes.None, - Size = new Vector2(72), + Size = new Vector2(visual_box_size), Child = transferContainerBox = new Box { Colour = Color4.White, From 456459cafa91f49981dd085e43312d10e9dc1255 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 13:25:24 +0900 Subject: [PATCH 130/278] Give flow container test long enough to finish --- .../Visual/UserInterface/TestCaseLogoFacadeContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs index 5f864eeabb..0b664a310a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs @@ -183,7 +183,7 @@ namespace osu.Game.Tests.Visual.UserInterface }, 700); }); - waitForMove(); + waitForMove(8); AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); } @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.UserInterface facadeContainer.SetLogo(logo, 1.0f, 1000); } - private void waitForMove() => AddWaitStep("Wait for transforms to finish", 5); + private void waitForMove(int count = 5) => AddWaitStep("Wait for transforms to finish", count); private void removeFacade() { From 6f5e9fe50d3976de9c1d686bce6e14c75ada64f8 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 4 Apr 2019 13:33:13 +0900 Subject: [PATCH 131/278] Correct xmldoc --- osu.Game/Graphics/Containers/LogoFacadeContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs index 1664fdde4d..c37588cb55 100644 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers /// /// Gets the position that the logo should move to with respect to the . - /// Manually performs a conversion of the Facade's position to the relative position of the Logo's Parent. + /// Manually performs a conversion of the Facade's position to the Logo's parent's relative space. /// /// Will only be correct if the logo's are set to Axes.Both /// The position that the logo should move to in its parent's relative space. From d54750aa37e5a94a6f1c34c4168c1e4876181b74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Apr 2019 17:10:29 +0900 Subject: [PATCH 132/278] Remove incorrect class --- .../Configuration/OsuConfigManager.cs | 32 ------------------- .../Configuration/OsuRulesetConfigManager.cs | 1 - 2 files changed, 33 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs deleted file mode 100644 index 492cc7cc7f..0000000000 --- a/osu.Game.Rulesets.Osu/Configuration/OsuConfigManager.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Configuration; -using osu.Game.Rulesets.Configuration; - -namespace osu.Game.Rulesets.Osu.Configuration -{ - public class OsuConfigManager : RulesetConfigManager - { - public OsuConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null) - : base(settings, ruleset, variant) - { - } - - protected override void InitialiseDefaults() - { - base.InitialiseDefaults(); - - Set(OsuSetting.SnakingInSliders, true); - Set(OsuSetting.SnakingOutSliders, true); - Set(OsuSetting.ShowCursorTrail, true); - } - } - - public enum OsuSetting - { - SnakingInSliders, - SnakingOutSliders, - ShowCursorTrail - } -} diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs index 872e152e0d..f76635a932 100644 --- a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs @@ -16,7 +16,6 @@ namespace osu.Game.Rulesets.Osu.Configuration protected override void InitialiseDefaults() { base.InitialiseDefaults(); - Set(OsuRulesetSetting.SnakingInSliders, true); Set(OsuRulesetSetting.SnakingOutSliders, true); Set(OsuRulesetSetting.ShowCursorTrail, true); From 9802d8ab1133d33e267afcb173efac0da82579e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Apr 2019 17:18:53 +0900 Subject: [PATCH 133/278] Rename setting --- osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 48eb74a74d..88adf72551 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.UI }, new SettingsCheckbox { - LabelText = "Show cursor trail", + LabelText = "Cursor trail", Bindable = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, }; From e13fffaca3dd5b520a5073234d83a99b44f10cc3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Apr 2019 16:32:04 +0900 Subject: [PATCH 134/278] Make ScoreTable use TableContainer --- .../Online/TestCaseBeatmapSetOverlay.cs | 3 - .../Visual/Online/TestCaseScoresContainer.cs | 3 - .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 184 +++++++++++++----- .../BeatmapSet/Scores/ScoreTableHeaderRow.cs | 54 ----- .../BeatmapSet/Scores/ScoreTableRow.cs | 104 ---------- .../BeatmapSet/Scores/ScoreTableScoreRow.cs | 114 ----------- 6 files changed, 136 insertions(+), 326 deletions(-) delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs delete mode 100644 osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs diff --git a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs index 9cbccbd603..8363f8be04 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseBeatmapSetOverlay.cs @@ -25,9 +25,6 @@ namespace osu.Game.Tests.Visual.Online { typeof(Header), typeof(ScoreTable), - typeof(ScoreTableRow), - typeof(ScoreTableHeaderRow), - typeof(ScoreTableScoreRow), typeof(ScoreTableRowBackground), typeof(DrawableTopScore), typeof(ScoresContainer), diff --git a/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs index 3d87e1743c..1ef4558691 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseScoresContainer.cs @@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual.Online typeof(TopScoreUserSection), typeof(TopScoreStatisticsSection), typeof(ScoreTable), - typeof(ScoreTableRow), - typeof(ScoreTableHeaderRow), - typeof(ScoreTableScoreRow), typeof(ScoreTableRowBackground), }; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 09ab0e3f6a..08e8dc7ecc 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -5,13 +5,26 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Chat; +using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTable : CompositeDrawable + public class ScoreTable : TableContainer { - private readonly ScoresGrid scoresGrid; + private const float horizontal_inset = 20; + private const float row_height = 25; + private const int text_size = 14; + private readonly FillFlowContainer backgroundFlow; public ScoreTable() @@ -19,77 +32,152 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChildren = new Drawable[] + Padding = new MarginPadding { Horizontal = horizontal_inset }; + RowSize = new Dimension(GridSizeMode.Absolute, row_height); + + AddInternal(backgroundFlow = new FillFlowContainer { - backgroundFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 25 } - }, - scoresGrid = new ScoresGrid - { - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Absolute, 40), - new Dimension(GridSizeMode.Absolute, 70), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed, minSize: 150), - new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70), - new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70), - new Dimension(GridSizeMode.AutoSize), - } - } - }; + RelativeSizeAxes = Axes.Both, + Depth = 1f, + Padding = new MarginPadding { Horizontal = -horizontal_inset }, + Margin = new MarginPadding { Top = row_height } + }); } public IReadOnlyList Scores { set { - scoresGrid.Content = new Drawable[0][]; + Content = null; backgroundFlow.Clear(); if (value == null || !value.Any()) return; - var content = new List - { - new ScoreTableHeaderRow(value.First()).CreateDrawables().ToArray() - }; - for (int i = 0; i < value.Count; i++) - { - content.Add(new ScoreTableScoreRow(i, value[i]).CreateDrawables().ToArray()); backgroundFlow.Add(new ScoreTableRowBackground(i)); - } - scoresGrid.Content = content.ToArray(); + Columns = createHeaders(value[0]); + Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } } - private class ScoresGrid : GridContainer + private TableColumn[] createHeaders(ScoreInfo score) { - public ScoresGrid() + var columns = new List { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; + new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), + new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade + new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), + new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), + new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 150)), + new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90)) + }; + + foreach (var statistic in score.Statistics) + columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70))); + + columns.AddRange(new[] + { + new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70)), + new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), + }); + + return columns.ToArray(); + } + + private Drawable[] createContent(int index, ScoreInfo score) + { + var content = new List + { + new OsuSpriteText + { + Text = $"#{index + 1}", + Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) + }, + new DrawableRank(score.Rank) + { + Size = new Vector2(30, 20) + }, + new OsuSpriteText + { + Margin = new MarginPadding { Right = horizontal_inset }, + Text = $@"{score.TotalScore:N0}", + Font = OsuFont.GetFont(size: text_size, weight: index == 0 ? FontWeight.Bold : FontWeight.Medium) + }, + new OsuSpriteText + { + Margin = new MarginPadding { Right = horizontal_inset }, + Text = $@"{score.Accuracy:P2}", + Font = OsuFont.GetFont(size: text_size), + Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White + }, + }; + + var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both }; + username.AddLink(score.User.Username, null, LinkAction.OpenUserProfile, score.User.Id.ToString(), "Open profile"); + + content.AddRange(new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Right = horizontal_inset }, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) }, + username + } + }, + new OsuSpriteText + { + Text = $@"{score.MaxCombo:N0}x", + Font = OsuFont.GetFont(size: text_size) + } + }); + + foreach (var kvp in score.Statistics) + { + content.Add(new OsuSpriteText + { + Text = $"{kvp.Value}", + Font = OsuFont.GetFont(size: text_size), + Colour = kvp.Value == 0 ? Color4.Gray : Color4.White + }); } - public Drawable[][] Content + content.AddRange(new Drawable[] { - get => base.Content; - set + new OsuSpriteText { - base.Content = value; + Text = $@"{score.PP:N0}", + Font = OsuFont.GetFont(size: text_size) + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) + { + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.3f) + }) + }, + }); - RowDimensions = Enumerable.Repeat(new Dimension(GridSizeMode.Absolute, 25), value.Length).ToArray(); - } + return content.ToArray(); + } + + protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty); + + private class HeaderText : OsuSpriteText + { + public HeaderText(string text) + { + Text = text.ToUpper(); + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs deleted file mode 100644 index f6f410a729..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableHeaderRow.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using osu.Framework.Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Scoring; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public class ScoreTableHeaderRow : ScoreTableRow - { - private readonly ScoreInfo score; - - public ScoreTableHeaderRow(ScoreInfo score) - { - this.score = score; - } - - protected override Drawable CreateIndexCell() => new CellText("rank"); - - protected override Drawable CreateRankCell() => new Container(); - - protected override Drawable CreateScoreCell() => new CellText("score"); - - protected override Drawable CreateAccuracyCell() => new CellText("accuracy"); - - protected override Drawable CreateUserCell() => new CellText("player"); - - protected override IEnumerable CreateStatisticsCells() - { - yield return new CellText("max combo"); - - foreach (var kvp in score.Statistics) - yield return new CellText(kvp.Key.GetDescription()); - } - - protected override Drawable CreatePpCell() => new CellText("pp"); - - protected override Drawable CreateModsCell() => new CellText("mods"); - - private class CellText : OsuSpriteText - { - public CellText(string text) - { - Text = text.ToUpper(); - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black); - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs deleted file mode 100644 index 15355512ba..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRow.cs +++ /dev/null @@ -1,104 +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.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public abstract class ScoreTableRow - { - protected const int TEXT_SIZE = 14; - - public IEnumerable CreateDrawables() - { - yield return new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, - Child = CreateIndexCell() - }; - - yield return new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Child = CreateRankCell() - }; - - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = 20 }, - Child = CreateScoreCell() - }; - - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = 20 }, - Child = CreateAccuracyCell() - }; - - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = 20 }, - Child = CreateUserCell() - }; - - foreach (var cell in CreateStatisticsCells()) - { - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Child = cell - }; - } - - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Child = CreatePpCell() - }; - - yield return new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = 20 }, - Child = CreateModsCell() - }; - } - - protected abstract Drawable CreateIndexCell(); - - protected abstract Drawable CreateRankCell(); - - protected abstract Drawable CreateScoreCell(); - - protected abstract Drawable CreateAccuracyCell(); - - protected abstract Drawable CreateUserCell(); - - protected abstract IEnumerable CreateStatisticsCells(); - - protected abstract Drawable CreatePpCell(); - - protected abstract Drawable CreateModsCell(); - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs deleted file mode 100644 index 75d45d0b23..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableScoreRow.cs +++ /dev/null @@ -1,114 +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.Collections.Generic; -using System.Linq; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.UI; -using osu.Game.Scoring; -using osu.Game.Users; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.BeatmapSet.Scores -{ - public class ScoreTableScoreRow : ScoreTableRow - { - private readonly int index; - private readonly ScoreInfo score; - - public ScoreTableScoreRow(int index, ScoreInfo score) - { - this.index = index; - this.score = score; - } - - protected override Drawable CreateIndexCell() => new OsuSpriteText - { - Text = $"#{index + 1}", - Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold) - }; - - protected override Drawable CreateRankCell() => new DrawableRank(score.Rank) - { - Size = new Vector2(30, 20), - }; - - protected override Drawable CreateScoreCell() => new OsuSpriteText - { - Text = $@"{score.TotalScore:N0}", - Font = OsuFont.GetFont(size: TEXT_SIZE, weight: index == 0 ? FontWeight.Bold : FontWeight.Medium) - }; - - protected override Drawable CreateAccuracyCell() => new OsuSpriteText - { - Text = $@"{score.Accuracy:P2}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White - }; - - protected override Drawable CreateUserCell() - { - var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE)) - { - AutoSizeAxes = Axes.Both, - }; - - username.AddLink(score.User.Username, null, LinkAction.OpenUserProfile, score.User.Id.ToString(), "Open profile"); - - return new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new DrawableFlag(score.User.Country) { Size = new Vector2(20, 13) }, - username - } - }; - } - - protected override IEnumerable CreateStatisticsCells() - { - yield return new OsuSpriteText - { - Text = $@"{score.MaxCombo:N0}x", - Font = OsuFont.GetFont(size: TEXT_SIZE) - }; - - foreach (var kvp in score.Statistics) - { - yield return new OsuSpriteText - { - Text = $"{kvp.Value}", - Font = OsuFont.GetFont(size: TEXT_SIZE), - Colour = kvp.Value == 0 ? Color4.Gray : Color4.White - }; - } - } - - protected override Drawable CreatePpCell() => new OsuSpriteText - { - Text = $@"{score.PP:N0}", - Font = OsuFont.GetFont(size: TEXT_SIZE) - }; - - protected override Drawable CreateModsCell() => new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f) - }) - }; - } -} From a6bf076dc7fe9c9777bf546285973df963170cae Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Apr 2019 17:58:34 +0900 Subject: [PATCH 135/278] Adjust green colour --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 08e8dc7ecc..3addef854a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -27,6 +28,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly FillFlowContainer backgroundFlow; + private Color4 highAccuracyColour; + public ScoreTable() { RelativeSizeAxes = Axes.X; @@ -44,6 +47,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }); } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + highAccuracyColour = colours.GreenLight; + } + public IReadOnlyList Scores { set @@ -110,7 +119,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Margin = new MarginPadding { Right = horizontal_inset }, Text = $@"{score.Accuracy:P2}", Font = OsuFont.GetFont(size: text_size), - Colour = score.Accuracy == 1 ? Color4.GreenYellow : Color4.White + Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, }; From 7047f305a1a7af92532d8902e4490f96119d23a9 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 12:02:47 +0900 Subject: [PATCH 136/278] Apply reviews, add safety for multiple facades --- ...er.cs => TestCaseLogoTrackingContainer.cs} | 71 ++++---- .../Containers/LogoFacadeContainer.cs | 114 ------------- .../Containers/LogoTrackingContainer.cs | 156 ++++++++++++++++++ osu.Game/Screens/Menu/ButtonSystem.cs | 24 +-- osu.Game/Screens/Menu/OsuLogo.cs | 6 + osu.Game/Screens/Play/PlayerLoader.cs | 23 +-- 6 files changed, 223 insertions(+), 171 deletions(-) rename osu.Game.Tests/Visual/UserInterface/{TestCaseLogoFacadeContainer.cs => TestCaseLogoTrackingContainer.cs} (77%) delete mode 100644 osu.Game/Graphics/Containers/LogoFacadeContainer.cs create mode 100644 osu.Game/Graphics/Containers/LogoTrackingContainer.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs similarity index 77% rename from osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs rename to osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 0b664a310a..4d255eb25a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoFacadeContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -21,13 +21,13 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestCaseLogoFacadeContainer : OsuTestCase + public class TestCaseLogoTrackingContainer : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(PlayerLoader), typeof(Player), - typeof(LogoFacadeContainer), + typeof(LogoTrackingContainer), typeof(ButtonSystem), typeof(ButtonSystemState), typeof(Menu), @@ -36,11 +36,11 @@ namespace osu.Game.Tests.Visual.UserInterface private OsuLogo logo; private readonly Bindable uiScale = new Bindable(); - private TestLogoFacadeContainer facadeContainer; + private TestLogoTrackingContainer trackingContainer; private Container transferContainer; private Box visualBox; private Box transferContainerBox; - private Container logoFacade; + private Drawable logoFacade; private bool randomPositions; private const float visual_box_size = 72; @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Clear(); Add(logo = new OsuLogo { Scale = new Vector2(0.15f), RelativePositionAxes = Axes.Both }); - facadeContainer = null; + trackingContainer = null; transferContainer = null; }); } @@ -72,10 +72,10 @@ namespace osu.Game.Tests.Visual.UserInterface public void MoveFacadeTest() { AddToggleStep("Toggle move continuously", b => randomPositions = b); - AddStep("Add facade containers", addFacadeContainers); + AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", startTrackingRandom); waitForMove(); - AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); + AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } /// @@ -84,11 +84,11 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void RemoveFacadeTest() { - AddStep("Add facade containers", addFacadeContainers); + AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", startTrackingRandom); AddStep("Remove facade from FacadeContainer", removeFacade); waitForMove(); - AddAssert("Logo is not tracking", () => !facadeContainer.IsLogoTracking); + AddAssert("Logo is not tracking", () => !trackingContainer.IsLogoTracking); } /// @@ -97,17 +97,12 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TransferFacadeTest() { - AddStep("Add facade containers", addFacadeContainers); + AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", startTrackingRandom); AddStep("Remove facade from FacadeContainer", removeFacade); - AddStep("Transfer facade to a new container", () => - { - transferContainer.Add(logoFacade); - transferContainerBox.Colour = Color4.Tomato; - moveLogoFacade(); - }); + AddStep("Transfer facade to a new container", addFacadeToNewContainer); waitForMove(); - AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); + AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } /// @@ -120,7 +115,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Create new flow container with facade", () => { - Add(facadeContainer = new TestLogoFacadeContainer + Add(trackingContainer = new TestLogoTrackingContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopCentre, @@ -156,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface Colour = Color4.White, RelativeSizeAxes = Axes.Both, }, - facadeContainer.LogoFacade, + trackingContainer.LogoFacade, } }, new Box @@ -171,27 +166,34 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Perform logo movements", () => { - facadeContainer.Tracking = false; + trackingContainer.Tracking = false; logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); - facadeContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); + trackingContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); visualBox.Colour = Color4.White; Scheduler.AddDelayed(() => { - facadeContainer.Tracking = true; + trackingContainer.Tracking = true; visualBox.Colour = Color4.Tomato; }, 700); }); waitForMove(8); - AddAssert("Logo is tracking", () => facadeContainer.IsLogoTracking); + AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); + } + + [Test] + public void SetFacadeSizeTest() + { + AddStep("Add tracking containers", addFacadeContainers); + AddStep("Break shit", () => { logoFacade.Size = new Vector2(0, 0); }); } private void addFacadeContainers() { AddRange(new Drawable[] { - facadeContainer = new TestLogoFacadeContainer + trackingContainer = new TestLogoTrackingContainer { Alpha = 0.35f, RelativeSizeAxes = Axes.None, @@ -215,22 +217,29 @@ namespace osu.Game.Tests.Visual.UserInterface }, }); - facadeContainer.Add(logoFacade = facadeContainer.LogoFacade); - facadeContainer.SetLogo(logo, 1.0f, 1000); + trackingContainer.Add(logoFacade = trackingContainer.LogoFacade); + trackingContainer.SetLogo(logo, 1.0f, 1000); } private void waitForMove(int count = 5) => AddWaitStep("Wait for transforms to finish", count); private void removeFacade() { - facadeContainer.Remove(logoFacade); + trackingContainer.Remove(logoFacade); visualBox.Colour = Color4.White; moveLogoFacade(); } private void startTrackingRandom() { - facadeContainer.Tracking = true; + trackingContainer.Tracking = true; + moveLogoFacade(); + } + + private void addFacadeToNewContainer() + { + transferContainer.Add(logoFacade); + transferContainerBox.Colour = Color4.Tomato; moveLogoFacade(); } @@ -239,7 +248,7 @@ namespace osu.Game.Tests.Visual.UserInterface if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) { Random random = new Random(); - facadeContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); + trackingContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); transferContainer.Delay(500).MoveTo(new Vector2(random.Next(0, (int)logo.Parent.DrawWidth), random.Next(0, (int)logo.Parent.DrawHeight)), 300); } @@ -247,12 +256,12 @@ namespace osu.Game.Tests.Visual.UserInterface Schedule(moveLogoFacade); } - private class TestLogoFacadeContainer : LogoFacadeContainer + private class TestLogoTrackingContainer : LogoTrackingContainer { /// /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. /// - public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition()); + public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition); } } } diff --git a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs b/osu.Game/Graphics/Containers/LogoFacadeContainer.cs deleted file mode 100644 index c37588cb55..0000000000 --- a/osu.Game/Graphics/Containers/LogoFacadeContainer.cs +++ /dev/null @@ -1,114 +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.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.MathUtils; -using osu.Game.Screens.Menu; -using osuTK; - -namespace osu.Game.Graphics.Containers -{ - /// - /// A container that creates a to be used to update and track the position of an . - /// - public class LogoFacadeContainer : Container - { - protected virtual Facade CreateFacade() => new Facade(); - - public Facade LogoFacade { get; } - - /// - /// Whether or not the logo assigned to this FacadeContainer should be tracking the position its facade. - /// - public bool Tracking = false; - - protected OsuLogo Logo; - - private float facadeScale; - private Easing easing; - private Vector2? startPosition; - private double? startTime; - private double duration; - - public LogoFacadeContainer() - { - LogoFacade = CreateFacade(); - } - - /// - /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. - /// - /// The instance of the logo to be used for tracking. - /// The scale of the facade. Does not actually affect the logo itself. - /// The duration of the initial transform. Default is instant. - /// The easing type of the initial transform. - public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) - { - Logo = logo ?? throw new ArgumentNullException(nameof(logo)); - this.facadeScale = facadeScale; - this.duration = duration; - this.easing = easing; - - startTime = null; - startPosition = null; - } - - /// - /// Gets the position that the logo should move to with respect to the . - /// Manually performs a conversion of the Facade's position to the Logo's parent's relative space. - /// - /// Will only be correct if the logo's are set to Axes.Both - /// The position that the logo should move to in its parent's relative space. - protected Vector2 LogoTrackingPosition() - { - Vector2 local; - local.X = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X; - local.Y = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y; - return local; - } - - protected override void Update() - { - base.Update(); - - if (Logo == null || !Tracking) - return; - - // Account for the scale of the actual logo container, as SizeForFlow only accounts for the sprite scale. - LogoFacade.Size = new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale); - - if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition()) - { - // If this is our first update since tracking has started, initialize our starting values for interpolation - if (startTime == null || startPosition == null) - { - startTime = Time.Current; - startPosition = Logo.Position; - } - - if (duration != 0) - { - double elapsedDuration = Time.Current - startTime ?? throw new ArgumentNullException(nameof(startTime)); - - var mount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); - - // Interpolate the position of the logo, where mount 0 is where the logo was when it first began interpolating, and mount 1 is the target location. - Logo.Position = Vector2.Lerp(startPosition ?? throw new ArgumentNullException(nameof(startPosition)), LogoTrackingPosition(), mount); - } - else - { - Logo.Position = LogoTrackingPosition(); - } - } - } - - /// - /// A placeholder container that serves as a dummy object to denote another object's location and size. - /// - public class Facade : Container - { - } - } -} diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs new file mode 100644 index 0000000000..afb30f981b --- /dev/null +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -0,0 +1,156 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.MathUtils; +using osu.Game.Screens.Menu; +using osuTK; + +namespace osu.Game.Graphics.Containers +{ + /// + /// A container that handles tracking of an through different layout scenarios + /// + public class LogoTrackingContainer : Container + { + public Facade LogoFacade { get; } + + /// + /// Whether or not the logo assigned to this FacadeContainer should be tracking the position of its facade. + /// + public bool Tracking { get; set; } + + protected OsuLogo Logo; + + private float facadeScale; + private Easing easing; + private Vector2? startPosition; + private double? startTime; + private double duration; + + public LogoTrackingContainer() + { + LogoFacade = new ExposedFacade(); + } + + /// + /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. + /// + /// The instance of the logo to be used for tracking. + /// The scale of the facade. Does not actually affect the logo itself. + /// The duration of the initial transform. Default is instant. + /// The easing type of the initial transform. + public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) + { + if (Logo != logo) + { + if (logo?.HasTrackingContainer ?? throw new ArgumentNullException(nameof(logo))) + { + // Prevent the same logo from being added to multiple LogoTrackingContainers. + throw new InvalidOperationException($"Cannot add an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); + } + + if (Logo != null) + { + // If we're replacing the logo to be tracked, the old one no longer has a tracking container + Logo.HasTrackingContainer = false; + } + } + + Logo = logo; + Logo.HasTrackingContainer = true; + this.facadeScale = facadeScale; + this.duration = duration; + this.easing = easing; + + startTime = null; + startPosition = null; + } + + /// + /// Gets the position that the logo should move to with respect to the . + /// Manually performs a conversion of the Facade's position to the Logo's parent's relative space. + /// + /// Will only be correct if the logo's are set to Axes.Both + protected Vector2 LogoTrackingPosition => new Vector2(Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X, + Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y); + + protected override void Update() + { + base.Update(); + + if (Logo == null || !Tracking) + return; + + // Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale. + ((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale)); + + if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition && Logo.RelativePositionAxes == Axes.Both) + { + // If this is our first update since tracking has started, initialize our starting values for interpolation + if (startTime == null || startPosition == null) + { + startTime = Time.Current; + startPosition = Logo.Position; + } + + if (duration != 0) + { + double elapsedDuration = (double)(Time.Current - startTime); + + var amount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); + + // Interpolate the position of the logo, where amount 0 is where the logo was when it first began interpolating, and amount 1 is the target location. + Logo.Position = Vector2.Lerp((Vector2)startPosition, LogoTrackingPosition, amount); + } + else + { + Logo.Position = LogoTrackingPosition; + } + } + } + + protected override void Dispose(bool isDisposing) + { + if (Logo != null) + Logo.HasTrackingContainer = false; + + base.Dispose(isDisposing); + } + + private Vector2 size; + + private class ExposedFacade : Facade + { + public override Vector2 Size + { + get => base.Size; + set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}"); + } + + public void SetSize(Vector2 size) + { + base.SetSize(size); + } + } + + /// + /// A dummy object used to denote another object's location. + /// + public abstract class Facade : Drawable + { + public override Vector2 Size + { + get => base.Size; + set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}"); + } + + protected void SetSize(Vector2 size) + { + base.Size = size; + } + } + } +} diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index cb95ec1765..a359893418 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Menu if (this.logo != null) { this.logo.Action = onOsuLogo; - logoFacadeContainer.SetLogo(logo, 0.74f); + logoTrackingContainer.SetLogo(logo, 0.74f); // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); @@ -70,7 +70,7 @@ namespace osu.Game.Screens.Menu else { // We should stop tracking as the facade is now out of scope. - logoFacadeContainer.Tracking = false; + logoTrackingContainer.Tracking = false; } } @@ -83,29 +83,29 @@ namespace osu.Game.Screens.Menu private SampleChannel sampleBack; - private readonly LogoFacadeContainer logoFacadeContainer; + private readonly LogoTrackingContainer logoTrackingContainer; public ButtonSystem() { RelativeSizeAxes = Axes.Both; - Child = logoFacadeContainer = new LogoFacadeContainer + Child = logoTrackingContainer = new LogoTrackingContainer { RelativeSizeAxes = Axes.Both, Child = buttonArea = new ButtonArea() }; - buttonArea.AddRange(new Container[] + buttonArea.AddRange(new Drawable[] { new Button(@"settings", string.Empty, FontAwesome.Gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O), backButton = new Button(@"back", @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH) { VisibleState = ButtonSystemState.Play, }, - logoFacadeContainer.LogoFacade + logoTrackingContainer.LogoFacade }); - buttonArea.Flow.CentreTarget = logoFacadeContainer.LogoFacade; + buttonArea.Flow.CentreTarget = logoTrackingContainer.LogoFacade; } [Resolved(CanBeNull = true)] @@ -271,7 +271,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - logoFacadeContainer.Tracking = false; + logoTrackingContainer.Tracking = false; game?.Toolbar.Hide(); @@ -294,8 +294,8 @@ namespace osu.Game.Screens.Menu if (lastState == ButtonSystemState.Initial) logo.ScaleTo(0.5f, 200, Easing.In); - logoFacadeContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); - logoFacadeContainer.Tracking = true; + logoTrackingContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); + logoTrackingContainer.Tracking = true; logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => @@ -308,14 +308,14 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); - logoFacadeContainer.Tracking = true; + logoTrackingContainer.Tracking = true; logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; } break; case ButtonSystemState.EnteringMode: - logoFacadeContainer.Tracking = true; + logoTrackingContainer.Tracking = true; break; } } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index c54ccd21b5..ad70d34637 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -54,8 +54,14 @@ namespace osu.Game.Screens.Menu /// public Func Action; + /// + /// The size of the logo Sprite with respect to the scale of its hover and bounce containers. + /// + /// Does not account for the scale of this public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X; + public bool HasTrackingContainer { get; set; } + private readonly Sprite ripple; private readonly Container rippleContainer; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index ccfd965f53..f7feb3535d 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play private Player player; - private LogoFacadeContainer content; + private LogoTrackingContainer content; private BeatmapMetadataDisplay info; @@ -60,14 +60,12 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - InternalChild = content = new LogoFacadeContainer + InternalChild = (content = new LogoTrackingContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - }; - - content.Children = new Drawable[] + }).WithChildren(new Drawable[] { info = new BeatmapMetadataDisplay(Beatmap.Value, content.LogoFacade) { @@ -89,7 +87,7 @@ namespace osu.Game.Screens.Play new InputSettings() } } - }; + }); loadNewPlayer(); } @@ -163,12 +161,9 @@ namespace osu.Game.Screens.Play logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); logo.FadeIn(350); - content.SetLogo(logo, 1.0f, 500, Easing.InOutExpo); + content.SetLogo(logo, 1.0f, resuming ? 0 : 500, Easing.InOutExpo); - Scheduler.AddDelayed(() => - { - content.Tracking = true; - }, resuming ? 0 : 500); + Scheduler.AddDelayed(() => { content.Tracking = true; }, resuming ? 0 : 500); } protected override void LogoExiting(OsuLogo logo) @@ -321,7 +316,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; - private readonly Container facade; + private readonly Drawable facade; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -343,7 +338,7 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Container facade) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Drawable facade) { this.beatmap = beatmap; this.facade = facade; @@ -366,7 +361,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Direction = FillDirection.Vertical, - Children = new Drawable[] + Children = new[] { facade, new OsuSpriteText From b1d74e57e58fc175fed9061dabed5f8e6d2e9642 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 13:56:08 +0900 Subject: [PATCH 137/278] Add checks guarding against setting tracking on multiple trackingcongtainers and setting facade size --- .../Containers/LogoTrackingContainer.cs | 48 ++++++++++--------- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index afb30f981b..ee6d5dec20 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Reflection.Metadata.Ecma335; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; @@ -20,7 +21,24 @@ namespace osu.Game.Graphics.Containers /// /// Whether or not the logo assigned to this FacadeContainer should be tracking the position of its facade. /// - public bool Tracking { get; set; } + public bool Tracking + { + get => tracking; + set + { + if (Logo != null) + { + if (value && !tracking && Logo.IsTracking) + throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); + + Logo.IsTracking = value; + } + + tracking = value; + } + } + + private bool tracking; protected OsuLogo Logo; @@ -44,23 +62,15 @@ namespace osu.Game.Graphics.Containers /// The easing type of the initial transform. public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) { - if (Logo != logo) + if (Logo != logo && Logo != null) { - if (logo?.HasTrackingContainer ?? throw new ArgumentNullException(nameof(logo))) - { - // Prevent the same logo from being added to multiple LogoTrackingContainers. - throw new InvalidOperationException($"Cannot add an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); - } - - if (Logo != null) - { - // If we're replacing the logo to be tracked, the old one no longer has a tracking container - Logo.HasTrackingContainer = false; - } + // If we're replacing the logo to be tracked, the old one no longer has a tracking container + Logo.IsTracking = false; } - Logo = logo; - Logo.HasTrackingContainer = true; + Logo = logo ?? throw new ArgumentNullException(nameof(logo)); + Logo.IsTracking = Tracking; + this.facadeScale = facadeScale; this.duration = duration; this.easing = easing; @@ -115,7 +125,7 @@ namespace osu.Game.Graphics.Containers protected override void Dispose(bool isDisposing) { if (Logo != null) - Logo.HasTrackingContainer = false; + Tracking = false; base.Dispose(isDisposing); } @@ -124,12 +134,6 @@ namespace osu.Game.Graphics.Containers private class ExposedFacade : Facade { - public override Vector2 Size - { - get => base.Size; - set => throw new InvalidOperationException($"Cannot set the Size of a {typeof(Facade)} outside of a {typeof(LogoTrackingContainer)}"); - } - public void SetSize(Vector2 size) { base.SetSize(size); diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index ad70d34637..4631f4e222 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Menu /// Does not account for the scale of this public float SizeForFlow => logo == null ? 0 : logo.DrawSize.X * logo.Scale.X * logoBounceContainer.Scale.X * logoHoverContainer.Scale.X; - public bool HasTrackingContainer { get; set; } + public bool IsTracking { get; set; } private readonly Sprite ripple; From 15fbb6f176395ae2ef5cc76c9cfe12ba2c53f6e4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Apr 2019 14:15:36 +0900 Subject: [PATCH 138/278] Use common AddUserLink method --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 4 ++++ osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 3 +-- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 3 +-- osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs | 3 +-- osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs | 5 ++--- osu.Game/Screens/Multi/Match/Components/HostInfo.cs | 4 +--- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index dace873b92..eefbeea24c 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Users; namespace osu.Game.Graphics.Containers { @@ -75,6 +76,9 @@ namespace osu.Game.Graphics.Containers return createLink(text, null, url, linkType, linkArgument, tooltipText); } + public IEnumerable AddUserLink(User user, Action creationParameters = null) + => createLink(AddText(user.Username, creationParameters), user.Username, null, LinkAction.OpenUserProfile, user.Id.ToString(), "View profile"); + private IEnumerable createLink(IEnumerable drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null) { AddInternal(new DrawableLinkCompiler(drawables.OfType().ToList()) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 3addef854a..693ce958dd 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -10,7 +10,6 @@ using osu.Framework.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.UI; using osu.Game.Scoring; @@ -124,7 +123,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }; var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both }; - username.AddLink(score.User.Username, null, LinkAction.OpenUserProfile, score.User.Id.ToString(), "Open profile"); + username.AddUserLink(score.User); content.AddRange(new Drawable[] { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index f401dc93a7..c0d9ecad3a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using osu.Game.Users; @@ -119,7 +118,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores date.Text = $@"achieved {value.Date.Humanize()}"; usernameText.Clear(); - usernameText.AddLink(value.User.Username, null, LinkAction.OpenUserProfile, value.User.Id.ToString(), "Open profile"); + usernameText.AddUserLink(value.User); rank.UpdateRank(value.Rank); } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index 23771451bd..d63f2fecd2 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Online.Chat; using osuTK; namespace osu.Game.Screens.Multi.Components @@ -60,7 +59,7 @@ namespace osu.Game.Screens.Multi.Components if (beatmap != null) { beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); - beatmapAuthor.AddLink(beatmap.Metadata.Author.Username, null, LinkAction.OpenUserProfile, beatmap.Metadata.Author.Id.ToString(), "View Profile"); + beatmapAuthor.AddUserLink(beatmap.Metadata.Author); } }, true); } diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 40e59de25d..51d3c93624 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; @@ -95,8 +94,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components if (host.NewValue != null) { hostText.AddText("hosted by "); - hostText.AddLink(host.NewValue.Username, null, LinkAction.OpenUserProfile, host.NewValue.Id.ToString(), "Open profile", - s => s.Font = s.Font.With(Typeface.Exo, weight: FontWeight.Bold, italics: true)); + hostText.AddUserLink(host.NewValue, s => s.Font = s.Font.With(Typeface.Exo, weight: FontWeight.Bold, italics: true)); + flagContainer.Child = new DrawableFlag(host.NewValue.Country) { RelativeSizeAxes = Axes.Both }; } }, true); diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs index 02c8929f44..b898cd0466 100644 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; @@ -54,8 +53,7 @@ namespace osu.Game.Screens.Multi.Match.Components { linkContainer.AddText("hosted by"); linkContainer.NewLine(); - linkContainer.AddLink(host.Username, null, LinkAction.OpenUserProfile, host.Id.ToString(), "View Profile", - s => s.Font = s.Font.With(Typeface.Exo, weight: FontWeight.Bold, italics: true)); + linkContainer.AddUserLink(host, s => s.Font = s.Font.With(Typeface.Exo, weight: FontWeight.Bold, italics: true)); } } } From a34a511f221e5d964772228d5feb1fb331fed543 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Apr 2019 14:55:25 +0900 Subject: [PATCH 139/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f3c648cf02..74ed9f91dd 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 7ce7329246..9fff64c61c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 5fa93f4a050263be0a2a546bcbfbd1bbc97e2771 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 15:05:11 +0900 Subject: [PATCH 140/278] Add test for checking exception --- .../UserInterface/TestCaseLogoTrackingContainer.cs | 12 +++++++++++- .../Graphics/Containers/LogoTrackingContainer.cs | 11 +++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 4d255eb25a..3b57d892ad 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -186,7 +186,17 @@ namespace osu.Game.Tests.Visual.UserInterface public void SetFacadeSizeTest() { AddStep("Add tracking containers", addFacadeContainers); - AddStep("Break shit", () => { logoFacade.Size = new Vector2(0, 0); }); + AddStep("Break stuff", () => { logoFacade.Size = new Vector2(0, 0); }); + } + + [Test] + public void SetMultipleContainers() + { + LogoTrackingContainer newContainer = new LogoTrackingContainer(); + AddStep("Add tracking containers", addFacadeContainers); + AddStep("Move facade to random position", startTrackingRandom); + AddStep("Add logo to new container", () => newContainer.SetLogo(logo)); + AddStep("Break stuff", () => newContainer.Tracking = true); } private void addFacadeContainers() diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index ee6d5dec20..ab6f7ebc2a 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Graphics.Containers { /// - /// A container that handles tracking of an through different layout scenarios + /// A container that handles tracking of an through different layout scenarios. /// public class LogoTrackingContainer : Container { @@ -38,8 +38,6 @@ namespace osu.Game.Graphics.Containers } } - private bool tracking; - protected OsuLogo Logo; private float facadeScale; @@ -47,6 +45,7 @@ namespace osu.Game.Graphics.Containers private Vector2? startPosition; private double? startTime; private double duration; + private bool tracking; public LogoTrackingContainer() { @@ -69,7 +68,11 @@ namespace osu.Game.Graphics.Containers } Logo = logo ?? throw new ArgumentNullException(nameof(logo)); - Logo.IsTracking = Tracking; + + if (Tracking) + { + Logo.IsTracking = true; + } this.facadeScale = facadeScale; this.duration = duration; From e06fe7950b04bec9df82a6244281b06faaf4892d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 15:06:37 +0900 Subject: [PATCH 141/278] Cleanup --- .../TestCaseLogoTrackingContainer.cs | 17 ----------------- .../Containers/LogoTrackingContainer.cs | 3 --- 2 files changed, 20 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 3b57d892ad..19e430da3e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -182,23 +182,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } - [Test] - public void SetFacadeSizeTest() - { - AddStep("Add tracking containers", addFacadeContainers); - AddStep("Break stuff", () => { logoFacade.Size = new Vector2(0, 0); }); - } - - [Test] - public void SetMultipleContainers() - { - LogoTrackingContainer newContainer = new LogoTrackingContainer(); - AddStep("Add tracking containers", addFacadeContainers); - AddStep("Move facade to random position", startTrackingRandom); - AddStep("Add logo to new container", () => newContainer.SetLogo(logo)); - AddStep("Break stuff", () => newContainer.Tracking = true); - } - private void addFacadeContainers() { AddRange(new Drawable[] diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index ab6f7ebc2a..746710bcda 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Reflection.Metadata.Ecma335; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; @@ -133,8 +132,6 @@ namespace osu.Game.Graphics.Containers base.Dispose(isDisposing); } - private Vector2 size; - private class ExposedFacade : Facade { public void SetSize(Vector2 size) From 37ffe47e4b763140befcea82f29cfe662869b2c4 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 15:30:09 +0900 Subject: [PATCH 142/278] Add back exception tests with better descriptions --- .../TestCaseLogoTrackingContainer.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 19e430da3e..cf84a34344 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -182,6 +182,49 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } + [Test] + public void SetFacadeSizeTest() + { + bool failed = false; + AddStep("Add tracking containers", addFacadeContainers); + AddStep("Try setting facade size", () => + { + try + { + logoFacade.Size = new Vector2(0, 0); + } + catch (Exception e) + { + if (e is InvalidOperationException) + failed = true; + } + }); + AddAssert("Exception thrown", () => failed); + } + + [Test] + public void SetMultipleContainers() + { + bool failed = false; + LogoTrackingContainer newContainer = new LogoTrackingContainer(); + AddStep("Add tracking containers", addFacadeContainers); + AddStep("Move facade to random position", startTrackingRandom); + AddStep("Add logo to new container", () => newContainer.SetLogo(logo)); + AddStep("Try tracking new container", () => + { + try + { + newContainer.Tracking = true; + } + catch (Exception e) + { + if (e is InvalidOperationException) + failed = true; + } + }); + AddAssert("Exception thrown", () => failed); + } + private void addFacadeContainers() { AddRange(new Drawable[] From c693d1fad89ea3b3d4ab655808668a6350bb9f6c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 15:48:48 +0900 Subject: [PATCH 143/278] Further condense steps --- .../TestCaseLogoTrackingContainer.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index cf84a34344..01a3113fe1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -100,7 +100,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", startTrackingRandom); AddStep("Remove facade from FacadeContainer", removeFacade); - AddStep("Transfer facade to a new container", addFacadeToNewContainer); + AddStep("Transfer facade to a new container", () => + { + transferContainer.Add(logoFacade); + transferContainerBox.Colour = Color4.Tomato; + moveLogoFacade(); + }); waitForMove(); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } @@ -186,7 +191,11 @@ namespace osu.Game.Tests.Visual.UserInterface public void SetFacadeSizeTest() { bool failed = false; - AddStep("Add tracking containers", addFacadeContainers); + AddStep("Set up scenario", () => + { + failed = false; + addFacadeContainers(); + }); AddStep("Try setting facade size", () => { try @@ -203,13 +212,18 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void SetMultipleContainers() + public void SetMultipleContainersTest() { bool failed = false; LogoTrackingContainer newContainer = new LogoTrackingContainer(); - AddStep("Add tracking containers", addFacadeContainers); - AddStep("Move facade to random position", startTrackingRandom); - AddStep("Add logo to new container", () => newContainer.SetLogo(logo)); + AddStep("Set up scenario", () => + { + failed = false; + newContainer = new LogoTrackingContainer(); + addFacadeContainers(); + startTrackingRandom(); + newContainer.SetLogo(logo); + }); AddStep("Try tracking new container", () => { try @@ -272,13 +286,6 @@ namespace osu.Game.Tests.Visual.UserInterface moveLogoFacade(); } - private void addFacadeToNewContainer() - { - transferContainer.Add(logoFacade); - transferContainerBox.Colour = Color4.Tomato; - moveLogoFacade(); - } - private void moveLogoFacade() { if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) From 53906e87ec35fcb657fd4700dd3039bc8d878347 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 5 Apr 2019 00:00:21 -0700 Subject: [PATCH 144/278] Split floatingOverlayContent --- osu.Game/OsuGame.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f19860a884..bb279a0bc2 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -399,7 +399,8 @@ namespace osu.Game } }, overlayContent = new Container { RelativeSizeAxes = Axes.Both }, - floatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, + rightFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, + leftFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, topMostOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, idleTracker = new GameIdleTracker(6000) }); @@ -427,6 +428,7 @@ namespace osu.Game }, }, topMostOverlayContent.Add); + loadComponentSingleFile(volume = new VolumeOverlay(), rightFloatingOverlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); loadComponentSingleFile(loginOverlay = new LoginOverlay @@ -434,7 +436,7 @@ namespace osu.Game GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - }, floatingOverlayContent.Add); + }, rightFloatingOverlayContent.Add); loadComponentSingleFile(screenshotManager, Add); @@ -443,6 +445,7 @@ namespace osu.Game loadComponentSingleFile(social = new SocialOverlay(), overlayContent.Add); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add); + loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset }, leftFloatingOverlayContent.Add); loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add); loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add); @@ -451,17 +454,14 @@ namespace osu.Game GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - }, floatingOverlayContent.Add); + }, rightFloatingOverlayContent.Add); loadComponentSingleFile(musicController = new MusicController { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - }, floatingOverlayContent.Add); - - loadComponentSingleFile(volume = new VolumeOverlay(), floatingOverlayContent.Add); - loadComponentSingleFile(settings = new MainSettings { GetToolbarHeight = () => ToolbarOffset }, floatingOverlayContent.Add); + }, rightFloatingOverlayContent.Add); loadComponentSingleFile(accountCreation = new AccountCreationOverlay(), topMostOverlayContent.Add); loadComponentSingleFile(dialogOverlay = new DialogOverlay(), topMostOverlayContent.Add); @@ -710,7 +710,9 @@ namespace osu.Game private Container overlayContent; - private Container floatingOverlayContent; + private Container rightFloatingOverlayContent; + + private Container leftFloatingOverlayContent; private Container topMostOverlayContent; From debda7ae7de8c0b4bd57fc48a9dec0c01723dd45 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 5 Apr 2019 00:05:42 -0700 Subject: [PATCH 145/278] Fix volume overlay container reference --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index bb279a0bc2..15cd6d73e5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -428,7 +428,7 @@ namespace osu.Game }, }, topMostOverlayContent.Add); - loadComponentSingleFile(volume = new VolumeOverlay(), rightFloatingOverlayContent.Add); + loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); loadComponentSingleFile(loginOverlay = new LoginOverlay From 0208526837180c9e19f7f297b7d5c49d0629398c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 5 Apr 2019 18:21:54 +0900 Subject: [PATCH 146/278] Fix button system visual issue --- osu.Game/Screens/Menu/Button.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 794fc093d3..383150cbd3 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -63,6 +63,8 @@ namespace osu.Game.Screens.Menu { box = new Container { + // box needs to be always present to ensure the button is always sized correctly for flow + AlwaysPresent = true, Masking = true, MaskingSmoothness = 2, EdgeEffect = new EdgeEffectParameters From cb3532e7d46a7b9614a4161463ac32a7c8aa2105 Mon Sep 17 00:00:00 2001 From: theFerdi265 Date: Sat, 6 Apr 2019 00:53:02 +0200 Subject: [PATCH 147/278] BeatmapLeaderboard: fix local scores not being sorted --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index ebb1d78ba0..042ef0f5a1 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards { if (Scope == BeatmapLeaderboardScope.Local) { - Scores = scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID).ToArray(); + Scores = scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID).OrderBy(s => -s.TotalScore).ToArray(); PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; return null; } From d5b7865ab8c73ae2f3aad743a190ef12d5ef983c Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 6 Apr 2019 17:40:48 +0200 Subject: [PATCH 148/278] Invert notification and loginOverlay depth order --- osu.Game/OsuGame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 15cd6d73e5..4f92ff831c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -431,7 +431,7 @@ namespace osu.Game loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); - loadComponentSingleFile(loginOverlay = new LoginOverlay + loadComponentSingleFile(notifications = new NotificationOverlay { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, @@ -449,7 +449,7 @@ namespace osu.Game loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add); loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add); - loadComponentSingleFile(notifications = new NotificationOverlay + loadComponentSingleFile(loginOverlay = new LoginOverlay { GetToolbarHeight = () => ToolbarOffset, Anchor = Anchor.TopRight, From 59410dbe3b739a5708604dddb8dd7e5df48236be Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 6 Apr 2019 18:05:13 +0200 Subject: [PATCH 149/278] Open login overlay when notification asking for signing in to play multi is clicked --- osu.Game/Screens/Menu/ButtonSystem.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index d3cf23dab8..77be5d08d9 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -103,6 +103,9 @@ namespace osu.Game.Screens.Menu [Resolved(CanBeNull = true)] private NotificationOverlay notifications { get; set; } + [Resolved] + private LoginOverlay loginOverlay { get; set; } + [BackgroundDependencyLoader(true)] private void load(AudioManager audio, IdleTracker idleTracker, GameHost host) { @@ -134,8 +137,13 @@ namespace osu.Game.Screens.Menu { notifications?.Post(new SimpleNotification { - Text = "You gotta be logged in to multi 'yo!", - Icon = FontAwesome.Solid.Globe + Text = "You gotta be logged in to multi 'yo!", + Icon = FontAwesome.Solid.Globe, + Activated = () => + { + loginOverlay.Show(); + return true; + } }); return; From 394f14965b88c745252a3932af9337c30d17037d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 6 Apr 2019 18:23:56 +0200 Subject: [PATCH 150/278] Make appveyor happy with whitespaces --- osu.Game/Screens/Menu/ButtonSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 77be5d08d9..d311664737 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -137,7 +137,7 @@ namespace osu.Game.Screens.Menu { notifications?.Post(new SimpleNotification { - Text = "You gotta be logged in to multi 'yo!", + Text = "You gotta be logged in to multi 'yo!", Icon = FontAwesome.Solid.Globe, Activated = () => { From 3f2e6a9376e024ada4a91e565f7b66b3eb232439 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 6 Apr 2019 18:52:30 +0200 Subject: [PATCH 151/278] Allow loginOverlay to be null if there's no cached instance in DI (for testing cases) --- osu.Game/Screens/Menu/ButtonSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index d311664737..80fbce2cf8 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Menu [Resolved(CanBeNull = true)] private NotificationOverlay notifications { get; set; } - [Resolved] + [Resolved(CanBeNull = true)] private LoginOverlay loginOverlay { get; set; } [BackgroundDependencyLoader(true)] @@ -141,7 +141,7 @@ namespace osu.Game.Screens.Menu Icon = FontAwesome.Solid.Globe, Activated = () => { - loginOverlay.Show(); + loginOverlay?.Show(); return true; } }); From d431ca4efc2f1cf384d0cf595213130792474445 Mon Sep 17 00:00:00 2001 From: Ferdinand Bachmann Date: Sun, 7 Apr 2019 13:26:35 +0200 Subject: [PATCH 152/278] BeatmapLeaderboard: use OrderByDescending instead of negation (suggested by peppy) --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 042ef0f5a1..aafa6bb0eb 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards { if (Scope == BeatmapLeaderboardScope.Local) { - Scores = scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID).OrderBy(s => -s.TotalScore).ToArray(); + Scores = scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID).OrderByDescending(s => s.TotalScore).ToArray(); PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; return null; } From d7655bc579df0a5193caa5cad65b02fd7084c3d8 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Mon, 8 Apr 2019 11:22:01 +0900 Subject: [PATCH 153/278] Use .Value instead of cast Co-Authored-By: nyquillerium --- osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index 746710bcda..de70231989 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -115,7 +115,7 @@ namespace osu.Game.Graphics.Containers var amount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); // Interpolate the position of the logo, where amount 0 is where the logo was when it first began interpolating, and amount 1 is the target location. - Logo.Position = Vector2.Lerp((Vector2)startPosition, LogoTrackingPosition, amount); + Logo.Position = Vector2.Lerp(startPosition.Value, LogoTrackingPosition, amount); } else { From a690302d00cefdae17fa150e1d567cb9669fbc9d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Mon, 8 Apr 2019 15:24:09 +0900 Subject: [PATCH 154/278] Apply reviews --- .../UserInterface/TestCaseButtonSystem.cs | 2 +- .../TestCaseLogoTrackingContainer.cs | 27 +++---- .../Containers/LogoTrackingContainer.cs | 78 +++++++++---------- osu.Game/Screens/Menu/ButtonSystem.cs | 13 ++-- .../Screens/Menu/FlowContainerWithOrigin.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 8 +- 6 files changed, 59 insertions(+), 71 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseButtonSystem.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseButtonSystem.cs index 261e87ff07..04aa8bce7e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseButtonSystem.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseButtonSystem.cs @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.UserInterface RelativeSizeAxes = Axes.Both, }, buttons = new ButtonSystem(), - logo = new OsuLogo() + logo = new OsuLogo { RelativePositionAxes = Axes.Both } }; buttons.SetOsuLogo(logo); diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 01a3113fe1..8b70a34c85 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.Visual.UserInterface { AddToggleStep("Toggle move continuously", b => randomPositions = b); AddStep("Add tracking containers", addFacadeContainers); - AddStep("Move facade to random position", startTrackingRandom); + AddStep("Move facade to random position", moveLogoFacade); waitForMove(); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.UserInterface public void RemoveFacadeTest() { AddStep("Add tracking containers", addFacadeContainers); - AddStep("Move facade to random position", startTrackingRandom); + AddStep("Move facade to random position", moveLogoFacade); AddStep("Remove facade from FacadeContainer", removeFacade); waitForMove(); AddAssert("Logo is not tracking", () => !trackingContainer.IsLogoTracking); @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.UserInterface public void TransferFacadeTest() { AddStep("Add tracking containers", addFacadeContainers); - AddStep("Move facade to random position", startTrackingRandom); + AddStep("Move facade to random position", moveLogoFacade); AddStep("Remove facade from FacadeContainer", removeFacade); AddStep("Transfer facade to a new container", () => { @@ -171,14 +171,14 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Perform logo movements", () => { - trackingContainer.Tracking = false; + trackingContainer.StopTracking(); logo.MoveTo(new Vector2(0.5f), 500, Easing.InOutExpo); - trackingContainer.SetLogo(logo, 1.0f, 1000, Easing.InOutExpo); + visualBox.Colour = Color4.White; Scheduler.AddDelayed(() => { - trackingContainer.Tracking = true; + trackingContainer.StartTracking(logo, 1000, Easing.InOutExpo); visualBox.Colour = Color4.Tomato; }, 700); }); @@ -221,14 +221,13 @@ namespace osu.Game.Tests.Visual.UserInterface failed = false; newContainer = new LogoTrackingContainer(); addFacadeContainers(); - startTrackingRandom(); - newContainer.SetLogo(logo); + moveLogoFacade(); }); AddStep("Try tracking new container", () => { try { - newContainer.Tracking = true; + newContainer.StartTracking(logo); } catch (Exception e) { @@ -268,7 +267,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); trackingContainer.Add(logoFacade = trackingContainer.LogoFacade); - trackingContainer.SetLogo(logo, 1.0f, 1000); + trackingContainer.StartTracking(logo, 1000); } private void waitForMove(int count = 5) => AddWaitStep("Wait for transforms to finish", count); @@ -280,12 +279,6 @@ namespace osu.Game.Tests.Visual.UserInterface moveLogoFacade(); } - private void startTrackingRandom() - { - trackingContainer.Tracking = true; - moveLogoFacade(); - } - private void moveLogoFacade() { if (logoFacade?.Transforms.Count == 0 && transferContainer?.Transforms.Count == 0) @@ -304,7 +297,7 @@ namespace osu.Game.Tests.Visual.UserInterface /// /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. /// - public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, LogoTrackingPosition); + public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, ComputeLogoTrackingPosition()); } } } diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index 746710bcda..ae585a2ba7 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -17,29 +17,9 @@ namespace osu.Game.Graphics.Containers { public Facade LogoFacade { get; } - /// - /// Whether or not the logo assigned to this FacadeContainer should be tracking the position of its facade. - /// - public bool Tracking - { - get => tracking; - set - { - if (Logo != null) - { - if (value && !tracking && Logo.IsTracking) - throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); + protected OsuLogo Logo => logo; - Logo.IsTracking = value; - } - - tracking = value; - } - } - - protected OsuLogo Logo; - - private float facadeScale; + private OsuLogo logo; private Easing easing; private Vector2? startPosition; private double? startTime; @@ -58,27 +38,38 @@ namespace osu.Game.Graphics.Containers /// The scale of the facade. Does not actually affect the logo itself. /// The duration of the initial transform. Default is instant. /// The easing type of the initial transform. - public void SetLogo(OsuLogo logo, float facadeScale = 1.0f, double duration = 0, Easing easing = Easing.None) + public void StartTracking(OsuLogo logo, double duration = 0, Easing easing = Easing.None) { - if (Logo != logo && Logo != null) + if (logo == null) + throw new ArgumentNullException(nameof(logo)); + + if (logo.IsTracking && tracking == false) + throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); + + if (this.logo != logo && this.logo != null) { // If we're replacing the logo to be tracked, the old one no longer has a tracking container - Logo.IsTracking = false; + this.logo.IsTracking = false; } - Logo = logo ?? throw new ArgumentNullException(nameof(logo)); + this.logo = logo; + this.logo.IsTracking = true; - if (Tracking) - { - Logo.IsTracking = true; - } - - this.facadeScale = facadeScale; this.duration = duration; this.easing = easing; startTime = null; startPosition = null; + + tracking = true; + } + + public void StopTracking() + { + if (logo != null) + logo.IsTracking = false; + + tracking = false; } /// @@ -86,20 +77,27 @@ namespace osu.Game.Graphics.Containers /// Manually performs a conversion of the Facade's position to the Logo's parent's relative space. /// /// Will only be correct if the logo's are set to Axes.Both - protected Vector2 LogoTrackingPosition => new Vector2(Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).X / Logo.Parent.RelativeToAbsoluteFactor.X, - Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre).Y / Logo.Parent.RelativeToAbsoluteFactor.Y); + protected Vector2 ComputeLogoTrackingPosition() + { + var absolutePos = Logo.Parent.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre); + + return new Vector2(absolutePos.X / Logo.Parent.RelativeToAbsoluteFactor.X, + absolutePos.Y / Logo.Parent.RelativeToAbsoluteFactor.Y); + } protected override void Update() { base.Update(); - if (Logo == null || !Tracking) + if (Logo == null || !tracking) return; // Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale. - ((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X * facadeScale)); + ((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X)); - if (LogoFacade.Parent != null && Logo.Position != LogoTrackingPosition && Logo.RelativePositionAxes == Axes.Both) + var localPos = ComputeLogoTrackingPosition(); + + if (LogoFacade.Parent != null && Logo.Position != localPos && Logo.RelativePositionAxes == Axes.Both) { // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == null || startPosition == null) @@ -115,11 +113,11 @@ namespace osu.Game.Graphics.Containers var amount = (float)Interpolation.ApplyEasing(easing, Math.Min(elapsedDuration / duration, 1)); // Interpolate the position of the logo, where amount 0 is where the logo was when it first began interpolating, and amount 1 is the target location. - Logo.Position = Vector2.Lerp((Vector2)startPosition, LogoTrackingPosition, amount); + Logo.Position = Vector2.Lerp((Vector2)startPosition, localPos, amount); } else { - Logo.Position = LogoTrackingPosition; + Logo.Position = localPos; } } } @@ -127,7 +125,7 @@ namespace osu.Game.Graphics.Containers protected override void Dispose(bool isDisposing) { if (Logo != null) - Tracking = false; + Logo.IsTracking = false; base.Dispose(isDisposing); } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index d042e110e9..1d2ee3c284 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -60,17 +60,17 @@ namespace osu.Game.Screens.Menu if (this.logo != null) { this.logo.Action = onOsuLogo; - logoTrackingContainer.SetLogo(logo, 0.74f); // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); + logoTrackingContainer.LogoFacade.Scale = new Vector2(0.74f); updateLogoState(); } else { // We should stop tracking as the facade is now out of scope. - logoTrackingContainer.Tracking = false; + logoTrackingContainer.StopTracking(); } } @@ -271,7 +271,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => { - logoTrackingContainer.Tracking = false; + logoTrackingContainer.StopTracking(); game?.Toolbar.Hide(); @@ -294,8 +294,7 @@ namespace osu.Game.Screens.Menu if (lastState == ButtonSystemState.Initial) logo.ScaleTo(0.5f, 200, Easing.In); - logoTrackingContainer.SetLogo(logo, 0.74f, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); - logoTrackingContainer.Tracking = true; + logoTrackingContainer.StartTracking(logo, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In); logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => @@ -308,14 +307,14 @@ namespace osu.Game.Screens.Menu break; default: logo.ClearTransforms(targetMember: nameof(Position)); - logoTrackingContainer.Tracking = true; + logoTrackingContainer.StartTracking(logo, 0, Easing.In); logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; } break; case ButtonSystemState.EnteringMode: - logoTrackingContainer.Tracking = true; + logoTrackingContainer.StartTracking(logo, 0, Easing.In); break; } } diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index ec7333ec02..8310ab06eb 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Menu if (CentreTarget == null) return base.OriginPosition; - return CentreTarget.DrawPosition + CentreTarget.DrawSize / 2; + return CentreTarget.DrawPosition + CentreTarget.DrawSize / 2 * CentreTarget.Scale; } } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index f7feb3535d..4c8f9a3539 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -128,7 +128,7 @@ namespace osu.Game.Screens.Play private void contentOut() { // Ensure the logo is no longer tracking before we scale the content - content.Tracking = false; + content.StopTracking(); content.ScaleTo(0.7f, 300, Easing.InQuint); content.FadeOut(250); @@ -161,15 +161,13 @@ namespace osu.Game.Screens.Play logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); logo.FadeIn(350); - content.SetLogo(logo, 1.0f, resuming ? 0 : 500, Easing.InOutExpo); - - Scheduler.AddDelayed(() => { content.Tracking = true; }, resuming ? 0 : 500); + Scheduler.AddDelayed(() => { content.StartTracking(logo, resuming ? 0 : 500, Easing.InOutExpo); }, resuming ? 0 : 500); } protected override void LogoExiting(OsuLogo logo) { base.LogoExiting(logo); - content.Tracking = false; + content.StopTracking(); } protected override void LoadComplete() From 8a01995668734e46e0630ce8b143fb446d868a1b Mon Sep 17 00:00:00 2001 From: David Zhao Date: Mon, 8 Apr 2019 16:14:41 +0900 Subject: [PATCH 155/278] Remove need for tracking bool and backing logo --- .../Containers/LogoTrackingContainer.cs | 27 +++++++++---------- osu.Game/Screens/Menu/ButtonSystem.cs | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index 0721011345..5ebdb7d45d 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -17,14 +17,12 @@ namespace osu.Game.Graphics.Containers { public Facade LogoFacade { get; } - protected OsuLogo Logo => logo; + protected OsuLogo Logo { get; private set; } - private OsuLogo logo; private Easing easing; private Vector2? startPosition; private double? startTime; private double duration; - private bool tracking; public LogoTrackingContainer() { @@ -43,33 +41,32 @@ namespace osu.Game.Graphics.Containers if (logo == null) throw new ArgumentNullException(nameof(logo)); - if (logo.IsTracking && tracking == false) + if (logo.IsTracking && Logo == null) throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); - if (this.logo != logo && this.logo != null) + if (Logo != logo && Logo != null) { // If we're replacing the logo to be tracked, the old one no longer has a tracking container - this.logo.IsTracking = false; + Logo.IsTracking = false; } - this.logo = logo; - this.logo.IsTracking = true; + Logo = logo; + Logo.IsTracking = true; this.duration = duration; this.easing = easing; startTime = null; startPosition = null; - - tracking = true; } public void StopTracking() { - if (logo != null) - logo.IsTracking = false; - - tracking = false; + if (Logo != null) + { + Logo.IsTracking = false; + Logo = null; + } } /// @@ -89,7 +86,7 @@ namespace osu.Game.Graphics.Containers { base.Update(); - if (Logo == null || !tracking) + if (Logo == null) return; // Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale. diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 1d2ee3c284..a6157cdb64 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -63,7 +63,6 @@ namespace osu.Game.Screens.Menu // osuLogo.SizeForFlow relies on loading to be complete. buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0); - logoTrackingContainer.LogoFacade.Scale = new Vector2(0.74f); updateLogoState(); } @@ -106,6 +105,7 @@ namespace osu.Game.Screens.Menu }); buttonArea.Flow.CentreTarget = logoTrackingContainer.LogoFacade; + logoTrackingContainer.LogoFacade.Scale = new Vector2(0.74f); } [Resolved(CanBeNull = true)] From 93b6cc00dfe96e2b4e26564bba09a92a0a7d0481 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 12:53:00 +0900 Subject: [PATCH 156/278] Fix OsuScreenDependencies using the incorrect parent --- osu.Game/Screens/OsuScreen.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 5034385969..fdbc1120bc 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -65,12 +65,12 @@ namespace osu.Game.Screens protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var deps = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, base.CreateChildDependencies(parent)); + OsuScreenDependencies screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); - Beatmap = deps.Beatmap; - Ruleset = deps.Ruleset; + Beatmap = screenDependencies.Beatmap; + Ruleset = screenDependencies.Ruleset; - return deps; + return base.CreateChildDependencies(screenDependencies); } protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen; From ca9f172a96f15ef9461418f6fc541ab50df3323c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 12:58:10 +0900 Subject: [PATCH 157/278] Use var --- osu.Game/Screens/OsuScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index fdbc1120bc..e0a25deecf 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - OsuScreenDependencies screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); + var screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); Beatmap = screenDependencies.Beatmap; Ruleset = screenDependencies.Ruleset; From c584967eb12adb64c26111e43d4f2fa790e7ec8b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 8 Apr 2019 18:32:05 +0900 Subject: [PATCH 158/278] Remove mods from workingbeatmap --- .../TestCaseAutoJuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../UI/DrawableCatchRuleset.cs | 6 ++-- .../Edit/DrawableManiaEditRuleset.cs | 6 ++-- .../Edit/ManiaHitObjectComposer.cs | 5 +-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../UI/DrawableManiaRuleset.cs | 5 +-- osu.Game.Rulesets.Osu.Tests/StackingTest.cs | 3 +- .../Edit/DrawableOsuEditRuleset.cs | 6 ++-- .../Edit/OsuHitObjectComposer.cs | 5 +-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../UI/DrawableOsuRuleset.cs | 6 ++-- .../TestCaseTaikoPlayfield.cs | 4 ++- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../UI/DrawableTaikoRuleset.cs | 6 ++-- .../Formats/LegacyBeatmapDecoderTest.cs | 3 +- .../TestCaseBackgroundScreenBeatmap.cs | 2 +- .../Visual/Gameplay/TestCaseAutoplay.cs | 2 +- .../Visual/Gameplay/TestCaseReplay.cs | 3 +- .../SongSelect/TestCasePlaySongSelect.cs | 4 +-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 35 ++++++++----------- osu.Game/OsuGame.cs | 3 +- .../Difficulty/DifficultyCalculator.cs | 3 +- .../Difficulty/PerformanceCalculator.cs | 3 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 5 +-- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 19 +++++----- osu.Game/Rulesets/UI/Playfield.cs | 12 ++++--- .../UI/Scrolling/DrawableScrollingRuleset.cs | 5 +-- .../Screens/Multi/Match/MatchSubScreen.cs | 2 -- osu.Game/Screens/OsuScreen.cs | 5 +++ osu.Game/Screens/OsuScreenDependencies.cs | 13 ++++--- .../Screens/Play/GameplayClockContainer.cs | 9 ++--- osu.Game/Screens/Play/HUDOverlay.cs | 7 ++-- osu.Game/Screens/Play/Player.cs | 14 ++++---- osu.Game/Screens/Play/PlayerLoader.cs | 10 ++++-- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 5 +-- osu.Game/Screens/Select/MatchSongSelect.cs | 6 +--- osu.Game/Screens/Select/SongSelect.cs | 6 ++-- osu.Game/Tests/Visual/AllPlayersTestCase.cs | 2 +- osu.Game/Tests/Visual/OsuTestCase.cs | 17 +++++---- osu.Game/Tests/Visual/PlayerTestCase.cs | 2 +- 43 files changed, 147 insertions(+), 116 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs index fbb2db33b0..a696ba4e7e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Player CreatePlayer(Ruleset ruleset) { - Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); return base.CreatePlayer(ruleset); } } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index aa00e182a9..544694fc8f 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableCatchRuleset(this, beatmap); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableCatchRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index ba0f5b90ba..4b75b54d41 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.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.Input; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -10,6 +11,7 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Catch.Scoring; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -23,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450); diff --git a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs index acafaffee6..0bfbf38832 100644 --- a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs +++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs @@ -1,10 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Graphics; using osuTK; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; @@ -14,8 +16,8 @@ namespace osu.Game.Rulesets.Mania.Edit { public new IScrollingInfo ScrollingInfo => base.ScrollingInfo; - public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 56c9471462..ebc94c86e2 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Compose.Components; using osuTK; @@ -41,9 +42,9 @@ namespace osu.Game.Rulesets.Mania.Edit public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns; - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) { - DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap); + DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); // This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it dependencies.CacheAs(DrawableRuleset.ScrollingInfo); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 0ff79d2836..02a9b5ed30 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableManiaRuleset(this, beatmap); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableManiaRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 1c1ec604f6..9d10657680 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Mania.Scoring; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; @@ -39,8 +40,8 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Bindable configDirection = new Bindable(); - public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { // Generate the bar lines double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue; diff --git a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs index e2f6b2164c..13c9985f47 100644 --- a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using NUnit.Framework; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Beatmaps; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Tests using (var reader = new StreamReader(stream)) { var beatmap = Decoder.GetDecoder(reader).Decode(reader); - var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo); + var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Enumerable.Empty()); var objects = converted.HitObjects.ToList(); diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index d9cb203bdf..0c3050bfb4 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -1,7 +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.Game.Beatmaps; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; using osuTK; @@ -10,8 +12,8 @@ namespace osu.Game.Rulesets.Osu.Edit { public class DrawableOsuEditRuleset : DrawableOsuRuleset { - public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 039ec5585e..9c4b6ee7aa 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders; @@ -23,8 +24,8 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - => new DrawableOsuEditRuleset(ruleset, beatmap); + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + => new DrawableOsuEditRuleset(ruleset, beatmap, mods); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 44bce5bed8..115271da85 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableOsuRuleset(this, beatmap); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableOsuRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index f6a3be40b0..c2954e1b3b 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.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 System.Linq; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; using osu.Game.Replays; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Objects; @@ -22,8 +24,8 @@ namespace osu.Game.Rulesets.Osu.UI { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; - public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs index 369cdd49d2..c42faea9f9 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -11,6 +12,7 @@ using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; @@ -86,7 +88,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, Height = 768, - Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap) } + Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap, Enumerable.Empty()) } }); } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 448b1b42bb..cb53ec890b 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableTaikoRuleset(this, beatmap); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableTaikoRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index f4b9c46dfc..76bdd37ed3 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.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.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; @@ -16,6 +17,7 @@ using osu.Framework.Input; using osu.Game.Configuration; using osu.Game.Input.Handlers; using osu.Game.Replays; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Taiko.UI @@ -26,8 +28,8 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Left; TimeRange.Value = 7000; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 02dff6993d..e181130774 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Catch.Beatmaps; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Osu; @@ -39,7 +40,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(6, working.BeatmapInfo.BeatmapVersion); Assert.AreEqual(6, working.Beatmap.BeatmapInfo.BeatmapVersion); - Assert.AreEqual(6, working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapVersion); + Assert.AreEqual(6, working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Enumerable.Empty()).BeatmapInfo.BeatmapVersion); } } diff --git a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs index 891b89e72d..e3875421b1 100644 --- a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs @@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Background AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddStep("Set default user settings", () => { - Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }); songSelect.DimLevel.Value = 0.7f; songSelect.BlurLevel.Value = 0.4f; }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs index a2d92b7861..c930e77e9e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); return new ScoreAccessiblePlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs index b98ce96fbb..2a72dc8242 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Play; @@ -15,7 +16,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo); + var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Enumerable.Empty()); return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod().CreateReplayScore(beatmap)); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs index d5bc452d75..bc644da9d5 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs @@ -175,12 +175,12 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("change ruleset", () => { - songSelect.CurrentBeatmap.Mods.ValueChanged += onModChange; + SelectedMods.ValueChanged += onModChange; songSelect.Ruleset.ValueChanged += onRulesetChange; Ruleset.Value = new TaikoRuleset().RulesetInfo; - songSelect.CurrentBeatmap.Mods.ValueChanged -= onModChange; + SelectedMods.ValueChanged -= onModChange; songSelect.Ruleset.ValueChanged -= onRulesetChange; }); diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 73aa12a3db..3e6033da9c 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -52,7 +52,7 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) { throw new NotImplementedException(); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 2e36d87024..bb13a8c0e7 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -11,7 +11,6 @@ using osu.Framework.IO.File; using System.IO; using System.Linq; using System.Threading; -using osu.Framework.Bindables; using osu.Game.IO.Serialization; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; @@ -28,16 +27,12 @@ namespace osu.Game.Beatmaps public readonly BeatmapMetadata Metadata; - public readonly Bindable> Mods = new Bindable>(new Mod[] { }); - protected WorkingBeatmap(BeatmapInfo beatmapInfo) { BeatmapInfo = beatmapInfo; BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - Mods.ValueChanged += _ => applyRateAdjustments(); - beatmap = new RecyclableLazy(() => { var b = GetBeatmap() ?? new Beatmap(); @@ -55,7 +50,7 @@ namespace osu.Game.Beatmaps { // we want to ensure that we always have a track, even if it's a fake one. var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap); - applyRateAdjustments(t); + // applyRateAdjustments(t); return t; }); @@ -87,7 +82,7 @@ namespace osu.Game.Beatmaps /// The to create a playable for. /// The converted . /// If could not be converted to . - public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset) + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IEnumerable mods) { var rulesetInstance = ruleset.CreateInstance(); @@ -98,19 +93,19 @@ namespace osu.Game.Beatmaps throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter})."); // Apply conversion mods - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in mods.OfType()) mod.ApplyToBeatmapConverter(converter); // Convert IBeatmap converted = converter.Convert(); // Apply difficulty mods - if (Mods.Value.Any(m => m is IApplicableToDifficulty)) + if (mods.Any(m => m is IApplicableToDifficulty)) { converted.BeatmapInfo = converted.BeatmapInfo.Clone(); converted.BeatmapInfo.BaseDifficulty = converted.BeatmapInfo.BaseDifficulty.Clone(); - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in mods.OfType()) mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); } @@ -122,7 +117,7 @@ namespace osu.Game.Beatmaps foreach (var obj in converted.HitObjects) obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty); - foreach (var mod in Mods.Value.OfType()) + foreach (var mod in mods.OfType()) foreach (var obj in converted.HitObjects) mod.ApplyToHitObject(obj); @@ -188,15 +183,15 @@ namespace osu.Game.Beatmaps /// public void RecycleTrack() => track.Recycle(); - private void applyRateAdjustments(Track t = null) - { - if (t == null && track.IsResultAvailable) t = Track; - if (t == null) return; - - t.ResetSpeedAdjustments(); - foreach (var mod in Mods.Value.OfType()) - mod.ApplyToClock(t); - } + // private void applyRateAdjustments(Track t = null) + // { + // if (t == null && track.IsResultAvailable) t = Track; + // if (t == null) return; + // + // t.ResetSpeedAdjustments(); + // foreach (var mod in Mods.Value.OfType()) + // mod.ApplyToClock(t); + // } public class RecyclableLazy { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4f92ff831c..2cef4f66a9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -293,9 +293,8 @@ namespace osu.Game performFromMainMenu(() => { ruleset.Value = databasedScoreInfo.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); - Beatmap.Value.Mods.Value = databasedScoreInfo.Mods; + selectedMods.Value = databasedScoreInfo.Mods; menuScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore))); }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index aad55f8a38..e181051737 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -39,8 +39,7 @@ namespace osu.Game.Rulesets.Difficulty { mods = mods.Select(m => m.CreateCopy()).ToArray(); - beatmap.Mods.Value = mods; - IBeatmap playableBeatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo); + IBeatmap playableBeatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods); var clock = new StopwatchClock(); mods.OfType().ForEach(m => m.ApplyToClock(clock)); diff --git a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs index 2b627ee8e6..9ab81b9580 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs @@ -26,8 +26,7 @@ namespace osu.Game.Rulesets.Difficulty Ruleset = ruleset; Score = score; - beatmap.Mods.Value = score.Mods; - Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo); + Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods); Attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 41de0c36fc..5219cb9581 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -14,6 +14,7 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; @@ -185,8 +186,8 @@ namespace osu.Game.Rulesets.Edit } internal override DrawableEditRuleset CreateDrawableRuleset() - => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value)); + => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Enumerable.Empty())); - protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap); + protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index cdfe02b60b..90fe25accf 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets /// The beatmap to create the hit renderer for. /// Unable to successfully load the beatmap to be usable with this ruleset. /// - public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap); + public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods); /// /// Creates a to convert a to one that is applicable for this . diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 27137d9f98..0ab07de1ac 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -11,7 +11,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; @@ -82,7 +81,9 @@ namespace osu.Game.Rulesets.UI /// /// The mods which are to be applied. /// - private readonly IEnumerable mods; + [Cached] + [Cached(typeof(IBindable>))] + private readonly Bindable> mods = new Bindable>(); private FrameStabilityContainer frameStabilityContainer; @@ -93,16 +94,18 @@ namespace osu.Game.Rulesets.UI /// /// The ruleset being represented. /// The beatmap to create the hit renderer for. - protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap) + protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IEnumerable mods) : base(ruleset) { - Debug.Assert(workingBeatmap != null, "DrawableRuleset initialized with a null beatmap."); + if (workingBeatmap == null) + throw new ArgumentException("Beatmap cannot be null.", nameof(workingBeatmap)); + + this.mods.Value = mods; RelativeSizeAxes = Axes.Both; - Beatmap = (Beatmap)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo); + Beatmap = (Beatmap)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods); - mods = workingBeatmap.Mods.Value; applyBeatmapMods(mods); KeyBindingInputManager = CreateInputManager(); @@ -157,7 +160,7 @@ namespace osu.Game.Rulesets.UI .WithChild(ResumeOverlay))); } - applyRulesetMods(mods, config); + applyRulesetMods(mods.Value, config); loadObjects(); } @@ -172,7 +175,7 @@ namespace osu.Game.Rulesets.UI Playfield.PostProcess(); - foreach (var mod in mods.OfType()) + foreach (var mod in mods.Value.OfType()) mod.ApplyToDrawableHitObjects(Playfield.HitObjectContainer.Objects); } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 48b950c070..6ea565af44 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -57,13 +57,15 @@ namespace osu.Game.Rulesets.UI hitObjectContainerLazy = new Lazy(CreateHitObjectContainer); } - private WorkingBeatmap beatmap; + [Resolved] + private IBindable beatmap { get; set; } + + [Resolved] + private IBindable> selectedMods { get; set; } [BackgroundDependencyLoader] - private void load(IBindable beatmap) + private void load() { - this.beatmap = beatmap.Value; - Cursor = CreateCursor(); if (Cursor != null) AddInternal(Cursor); @@ -123,7 +125,7 @@ namespace osu.Game.Rulesets.UI base.Update(); if (beatmap != null) - foreach (var mod in beatmap.Mods.Value) + foreach (var mod in selectedMods.Value) if (mod is IUpdatableByPlayfield updatable) updatable.Update(this); } diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 3b368652f2..2bb98dd679 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Configuration; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; @@ -80,8 +81,8 @@ namespace osu.Game.Rulesets.UI.Scrolling [Cached(Type = typeof(IScrollingInfo))] private readonly LocalScrollingInfo scrollingInfo; - protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap) - : base(ruleset, beatmap) + protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + : base(ruleset, beatmap, mods) { scrollingInfo = new LocalScrollingInfo(); scrollingInfo.Direction.BindTo(Direction); diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a71106872e..b3f9a4ae21 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -222,8 +222,6 @@ namespace osu.Game.Screens.Multi.Match private void onStart() { - Beatmap.Value.Mods.Value = SelectedMods.Value.ToArray(); - switch (type.Value) { default: diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index e0a25deecf..33e725eb41 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -14,6 +15,7 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using osu.Game.Overlays; +using osu.Game.Rulesets.Mods; namespace osu.Game.Screens { @@ -63,12 +65,15 @@ namespace osu.Game.Screens public Bindable Ruleset { get; set; } + public Bindable> SelectedMods { get; set; } + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { var screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); Beatmap = screenDependencies.Beatmap; Ruleset = screenDependencies.Ruleset; + SelectedMods = screenDependencies.SelectedMods; return base.CreateChildDependencies(screenDependencies); } diff --git a/osu.Game/Screens/OsuScreenDependencies.cs b/osu.Game/Screens/OsuScreenDependencies.cs index 84e5de76de..9cc415f581 100644 --- a/osu.Game/Screens/OsuScreenDependencies.cs +++ b/osu.Game/Screens/OsuScreenDependencies.cs @@ -1,10 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; namespace osu.Game.Screens { @@ -14,6 +16,8 @@ namespace osu.Game.Screens public Bindable Ruleset { get; } + public Bindable> SelectedMods { get; } + public OsuScreenDependencies(bool requireLease, IReadOnlyDependencyContainer parent) : base(parent) { @@ -21,20 +25,21 @@ namespace osu.Game.Screens { Beatmap = parent.Get>()?.GetBoundCopy(); if (Beatmap == null) - { Cache(Beatmap = parent.Get>().BeginLease(false)); - } Ruleset = parent.Get>()?.GetBoundCopy(); if (Ruleset == null) - { Cache(Ruleset = parent.Get>().BeginLease(true)); - } + + SelectedMods = parent.Get>>()?.GetBoundCopy(); + if (SelectedMods == null) + Cache(SelectedMods = parent.Get>>().BeginLease(true)); } else { Beatmap = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); Ruleset = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); + SelectedMods = (parent.Get>>() ?? parent.Get>>()).GetBoundCopy(); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index c13222c6de..b17286f69e 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework; @@ -22,7 +23,7 @@ namespace osu.Game.Screens.Play /// public class GameplayClockContainer : Container { - private readonly WorkingBeatmap beatmap; + private readonly IEnumerable mods; /// /// The original source (usually a 's track). @@ -54,9 +55,9 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock offsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, IEnumerable mods, double gameplayStartTime) { - this.beatmap = beatmap; + this.mods = mods; RelativeSizeAxes = Axes.Both; @@ -154,7 +155,7 @@ namespace osu.Game.Screens.Play else sourceClock.Rate = UserPlaybackRate.Value; - foreach (var mod in beatmap.Mods.Value.OfType()) + foreach (var mod in mods.OfType()) mod.ApplyToClock(sourceClock); } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index a7b7f96e7a..aa4375f652 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -2,16 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; -using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play.HUD; @@ -42,7 +43,7 @@ namespace osu.Game.Screens.Play public Action RequestSeek; - public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, WorkingBeatmap working) + public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IEnumerable mods) { RelativeSizeAxes = Axes.Both; @@ -96,7 +97,7 @@ namespace osu.Game.Screens.Play Progress.AllowSeeking = drawableRuleset.HasReplayLoaded.Value; Progress.RequestSeek = time => RequestSeek(time); - ModDisplay.Current.BindTo(working.Mods); + ModDisplay.Current.Value = mods; } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0eebefec86..bf2bbc58b8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(working, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(working, SelectedMods.Value, DrawableRuleset.GameplayStartTime); GameplayClockContainer.Children = new[] { @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Play }, // display the cursor above some HUD elements. DrawableRuleset.Cursor?.CreateProxy() ?? new Container(), - HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, working) + HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, SelectedMods.Value) { HoldToQuit = { Action = performUserRequestedExit }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, @@ -170,7 +170,7 @@ namespace osu.Game.Screens.Play ScoreProcessor.AllJudged += onCompletion; ScoreProcessor.Failed += onFail; - foreach (var mod in Beatmap.Value.Mods.Value.OfType()) + foreach (var mod in SelectedMods.Value.OfType()) mod.ApplyToScoreProcessor(ScoreProcessor); } @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Play try { - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(working); + DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(working, SelectedMods.Value); } catch (BeatmapInvalidForRulesetException) { @@ -200,7 +200,7 @@ namespace osu.Game.Screens.Play // let's try again forcing the beatmap's ruleset. ruleset = beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(Beatmap.Value); + DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(Beatmap.Value, SelectedMods.Value); } if (!DrawableRuleset.Objects.Any()) @@ -271,7 +271,7 @@ namespace osu.Game.Screens.Play { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, - Mods = Beatmap.Value.Mods.Value.ToArray(), + Mods = SelectedMods.Value.ToArray(), User = api.LocalUser.Value, }; @@ -325,7 +325,7 @@ namespace osu.Game.Screens.Play private bool onFail() { - if (Beatmap.Value.Mods.Value.OfType().Any(m => !m.AllowFail)) + if (SelectedMods.Value.OfType().Any(m => !m.AllowFail)) return false; GameplayClockContainer.Stop(); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index e9ee5d3fa8..70f5736786 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -16,6 +17,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Menu; using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.PlayerSettings; @@ -66,7 +68,7 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - info = new BeatmapMetadataDisplay(Beatmap.Value) + info = new BeatmapMetadataDisplay(Beatmap.Value, SelectedMods.Value) { Alpha = 0, Anchor = Anchor.Centre, @@ -299,6 +301,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; + private readonly IEnumerable mods; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -320,9 +323,10 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, IEnumerable mods) { this.beatmap = beatmap; + this.mods = mods; } [BackgroundDependencyLoader] @@ -403,7 +407,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Top = 20 }, - Current = beatmap.Mods + Current = { Value = mods } } }, } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index d32387c1d3..03cf767062 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -25,6 +25,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Select @@ -309,12 +310,12 @@ namespace osu.Game.Screens.Select try { // Try to get the beatmap with the user's ruleset - playableBeatmap = beatmap.GetPlayableBeatmap(ruleset); + playableBeatmap = beatmap.GetPlayableBeatmap(ruleset, Enumerable.Empty()); } catch (BeatmapInvalidForRulesetException) { // Can't be converted to the user's ruleset, so use the beatmap's own ruleset - playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset); + playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset, Enumerable.Empty()); } labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s))); diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index fa5dc4c1d1..bc33750d6f 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using Humanizer; using osu.Framework.Allocation; @@ -26,9 +25,6 @@ namespace osu.Game.Screens.Select [Resolved(typeof(Room))] protected Bindable CurrentItem { get; private set; } - [Resolved] - private Bindable> selectedMods { get; set; } - [Resolved] private BeatmapManager beatmaps { get; set; } @@ -65,7 +61,7 @@ namespace osu.Game.Screens.Select { Ruleset.Value = CurrentItem.Value.Ruleset; Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap); - Beatmap.Value.Mods.Value = selectedMods.Value = CurrentItem.Value.RequiredMods ?? Enumerable.Empty(); + SelectedMods.Value = CurrentItem.Value.RequiredMods ?? Enumerable.Empty(); } Beatmap.Disabled = true; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b60e693cbf..64e64edce2 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -394,7 +394,7 @@ namespace osu.Game.Screens.Select { Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); - Beatmap.Value.Mods.Value = Enumerable.Empty(); + SelectedMods.Value = Enumerable.Empty(); decoupledRuleset.Value = ruleset; // force a filter before attempting to change the beatmap. @@ -530,7 +530,7 @@ namespace osu.Game.Screens.Select Beatmap.Value.Track.Looping = false; SelectedMods.UnbindAll(); - Beatmap.Value.Mods.Value = new Mod[] { }; + base.SelectedMods.Value = Enumerable.Empty(); return false; } @@ -557,8 +557,6 @@ namespace osu.Game.Screens.Select /// The working beatmap. protected virtual void UpdateBeatmap(WorkingBeatmap beatmap) { - beatmap.Mods.BindTo(SelectedMods); - Logger.Log($"working beatmap updated to {beatmap}"); if (Background is BackgroundScreenBeatmap backgroundModeBeatmap) diff --git a/osu.Game/Tests/Visual/AllPlayersTestCase.cs b/osu.Game/Tests/Visual/AllPlayersTestCase.cs index 4ef9b346b0..21955da6e9 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestCase.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestCase.cs @@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual var working = CreateWorkingBeatmap(beatmap, Clock); Beatmap.Value = working; - Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; + SelectedMods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; Player?.Exit(); Player = null; diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 495c5dfbad..9dab981ed5 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -10,16 +11,26 @@ using osu.Framework.Platform; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual { public abstract class OsuTestCase : TestCase { + [Cached(typeof(Bindable))] + [Cached(typeof(IBindable))] private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); + protected BindableBeatmap Beatmap => beatmap; + [Cached] + [Cached(typeof(IBindable))] protected readonly Bindable Ruleset = new Bindable(); + [Cached] + [Cached(Type = typeof(IBindable>))] + protected readonly Bindable> SelectedMods = new Bindable>(); + protected DependencyContainer Dependencies { get; private set; } private readonly Lazy localStorage; @@ -32,12 +43,6 @@ namespace osu.Game.Tests.Visual // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures beatmap.Default = new DummyWorkingBeatmap(Dependencies.Get()); - Dependencies.CacheAs>(beatmap); - Dependencies.CacheAs>(beatmap); - - Dependencies.CacheAs(Ruleset); - Dependencies.CacheAs>(Ruleset); - return Dependencies; } diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index 3bf707fade..409e79b4a5 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual Beatmap.Value = new TestWorkingBeatmap(beatmap, Clock); if (!AllowFail) - Beatmap.Value.Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; + SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; Player = CreatePlayer(ruleset); LoadScreen(Player); From ad124bfeec6745939b172f310618d2b6c5a99656 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 8 Apr 2019 19:16:34 +0900 Subject: [PATCH 159/278] Reimplement select mod track adjustments --- osu.Game/Beatmaps/WorkingBeatmap.cs | 19 +------------------ osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/MusicController.cs | 22 ++++++++++++++++++++-- osu.Game/Screens/OsuScreen.cs | 6 +++--- osu.Game/Screens/Select/SongSelect.cs | 15 ++++++++------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bb13a8c0e7..ec0a76b52b 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -46,14 +46,7 @@ namespace osu.Game.Beatmaps return b; }); - track = new RecyclableLazy(() => - { - // we want to ensure that we always have a track, even if it's a fake one. - var t = GetTrack() ?? new VirtualBeatmapTrack(Beatmap); - // applyRateAdjustments(t); - return t; - }); - + track = new RecyclableLazy(() => GetTrack() ?? new VirtualBeatmapTrack(Beatmap)); background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); @@ -183,16 +176,6 @@ namespace osu.Game.Beatmaps /// public void RecycleTrack() => track.Recycle(); - // private void applyRateAdjustments(Track t = null) - // { - // if (t == null && track.IsResultAvailable) t = Track; - // if (t == null) return; - // - // t.ResetSpeedAdjustments(); - // foreach (var mod in Mods.Value.OfType()) - // mod.ApplyToClock(t); - // } - public class RecyclableLazy { private Lazy lazy; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2cef4f66a9..4d889677a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -113,7 +113,7 @@ namespace osu.Game // todo: move this to SongSelect once Screen has the ability to unsuspend. [Cached] [Cached(Type = typeof(IBindable>))] - private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); + private readonly Bindable> selectedMods = new Bindable>(Enumerable.Empty()); public OsuGame(string[] args = null) { diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b24c6c3508..0ad4da2ce9 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -22,6 +22,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Music; +using osu.Game.Rulesets.Mods; using osuTK; using osuTK.Graphics; @@ -54,7 +55,11 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; - private readonly Bindable beatmap = new Bindable(); + [Resolved] + private Bindable beatmap { get; set; } + + [Resolved] + private IBindable> selectedMods { get; set; } /// /// Provide a source for the toolbar height. @@ -73,7 +78,6 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(Bindable beatmap, BeatmapManager beatmaps, OsuColour colours) { - this.beatmap.BindTo(beatmap); this.beatmaps = beatmaps; Children = new Drawable[] @@ -231,6 +235,7 @@ namespace osu.Game.Overlays { beatmap.BindValueChanged(beatmapChanged, true); beatmap.BindDisabledChanged(beatmapDisabledChanged, true); + selectedMods.BindValueChanged(_ => updateAudioAdjustments(), true); base.LoadComplete(); } @@ -354,10 +359,23 @@ namespace osu.Game.Overlays progressBar.CurrentTime = 0; updateDisplay(current, direction); + updateAudioAdjustments(); queuedDirection = null; } + private void updateAudioAdjustments() + { + var track = current?.Track; + if (track == null) + return; + + track.ResetSpeedAdjustments(); + + foreach (var mod in selectedMods.Value.OfType()) + mod.ApplyToClock(track); + } + private void currentTrackCompleted() => Schedule(() => { if (!current.Track.Looping && !beatmap.Disabled && beatmapSets.Any()) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 33e725eb41..bd7f326b50 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -61,11 +61,11 @@ namespace osu.Game.Screens public virtual float BackgroundParallaxAmount => 1; - public Bindable Beatmap { get; set; } + public Bindable Beatmap { get; private set; } - public Bindable Ruleset { get; set; } + public Bindable Ruleset { get; private set; } - public Bindable> SelectedMods { get; set; } + public Bindable> SelectedMods { get; private set; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 64e64edce2..0b6bb6f570 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -83,9 +83,7 @@ namespace osu.Game.Screens.Select private readonly Bindable decoupledRuleset = new Bindable(); - [Cached] - [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> SelectedMods = new Bindable>(new Mod[] { }); + protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); protected SongSelect() { @@ -217,11 +215,8 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, Bindable> selectedMods) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins) { - if (selectedMods != null) - SelectedMods.BindTo(selectedMods); - if (Footer != null) { Footer.AddButton(@"mods", colours.Yellow, ModSelect, Key.F1); @@ -269,6 +264,12 @@ namespace osu.Game.Screens.Select protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + + SelectedMods.BindTo(base.SelectedMods); + + dependencies.CacheAs(SelectedMods); + dependencies.CacheAs>>(SelectedMods); + dependencies.CacheAs(this); dependencies.CacheAs(decoupledRuleset); dependencies.CacheAs>(decoupledRuleset); From cbb3fdaca8f0fe2bc05f7839c5e9d57c07dac573 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 12:44:03 +0900 Subject: [PATCH 160/278] Fix various crashes due to bindable being disabled --- .../Visual/SongSelect/TestCasePlaySongSelect.cs | 8 ++------ osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 4 ---- osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 7 +------ osu.Game/Screens/Select/MatchSongSelect.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 17 ++++++++--------- 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs index bc644da9d5..a70529b384 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs @@ -35,10 +35,6 @@ namespace osu.Game.Tests.Visual.SongSelect private WorkingBeatmap defaultBeatmap; private DatabaseContextFactory factory; - [Cached] - [Cached(Type = typeof(IBindable>))] - private readonly Bindable> selectedMods = new Bindable>(new Mod[] { }); - public override IReadOnlyList RequiredTypes => new[] { typeof(Screens.Select.SongSelect), @@ -185,7 +181,7 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); - AddAssert("empty mods", () => !selectedMods.Value.Any()); + AddAssert("empty mods", () => !SelectedMods.Value.Any()); void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex--; @@ -218,7 +214,7 @@ namespace osu.Game.Tests.Visual.SongSelect private static int importId; private int getImportId() => ++importId; - private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => selectedMods.Value = mods); + private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => SelectedMods.Value = mods); private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id)); diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index b3f9a4ae21..e5ab46ebe2 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.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.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -42,9 +41,6 @@ namespace osu.Game.Screens.Multi.Match [Resolved(typeof(Room))] protected Bindable CurrentItem { get; private set; } - [Resolved] - protected Bindable> SelectedMods { get; private set; } - [Resolved] private BeatmapManager beatmapManager { get; set; } diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index d5b8f1f0c8..8ce68ac593 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; @@ -14,7 +13,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Multi.Ranking; using osu.Game.Screens.Play; @@ -37,9 +35,6 @@ namespace osu.Game.Screens.Multi.Play [Resolved] private IBindable ruleset { get; set; } - [Resolved] - private Bindable> selectedMods { get; set; } - public TimeshiftPlayer(PlaylistItem playlistItem) { this.playlistItem = playlistItem; @@ -61,7 +56,7 @@ namespace osu.Game.Screens.Multi.Play if (ruleset.Value.ID != playlistItem.Ruleset.ID) throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset"); - if (!playlistItem.RequiredMods.All(m => selectedMods.Value.Contains(m))) + if (!playlistItem.RequiredMods.All(m => SelectedMods.Value.Contains(m))) throw new InvalidOperationException("Current Mods do not match PlaylistItem's RequiredMods"); var req = new CreateRoomScoreRequest(roomId.Value ?? 0, playlistItem.ID); diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index bc33750d6f..1011f6f32d 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -66,6 +66,7 @@ namespace osu.Game.Screens.Select Beatmap.Disabled = true; Ruleset.Disabled = true; + SelectedMods.Disabled = true; return false; } @@ -76,6 +77,7 @@ namespace osu.Game.Screens.Select Beatmap.Disabled = false; Ruleset.Disabled = false; + SelectedMods.Disabled = false; } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0b6bb6f570..2bb646750c 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -83,7 +83,9 @@ namespace osu.Game.Screens.Select private readonly Bindable decoupledRuleset = new Bindable(); - protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); + [Cached] + [Cached(Type = typeof(IBindable>))] + private readonly Bindable> selectedMods = new Bindable>(Enumerable.Empty()); // Bound to the game's mods, but is not reset on exiting protected SongSelect() { @@ -217,6 +219,8 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins) { + selectedMods.BindTo(SelectedMods); + if (Footer != null) { Footer.AddButton(@"mods", colours.Yellow, ModSelect, Key.F1); @@ -265,11 +269,6 @@ namespace osu.Game.Screens.Select { dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - SelectedMods.BindTo(base.SelectedMods); - - dependencies.CacheAs(SelectedMods); - dependencies.CacheAs>>(SelectedMods); - dependencies.CacheAs(this); dependencies.CacheAs(decoupledRuleset); dependencies.CacheAs>(decoupledRuleset); @@ -395,7 +394,7 @@ namespace osu.Game.Screens.Select { Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); - SelectedMods.Value = Enumerable.Empty(); + selectedMods.Value = Enumerable.Empty(); decoupledRuleset.Value = ruleset; // force a filter before attempting to change the beatmap. @@ -530,8 +529,8 @@ namespace osu.Game.Screens.Select if (Beatmap.Value.Track != null) Beatmap.Value.Track.Looping = false; - SelectedMods.UnbindAll(); - base.SelectedMods.Value = Enumerable.Empty(); + selectedMods.UnbindAll(); + SelectedMods.Value = Enumerable.Empty(); return false; } From 56496d28ba9575ea75b37dd0e02243433a292bea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 12:50:54 +0900 Subject: [PATCH 161/278] Reset mods when exiting match --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index e5ab46ebe2..5f29044c76 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -178,6 +178,9 @@ namespace osu.Game.Screens.Multi.Match public override bool OnExiting(IScreen next) { RoomManager?.PartRoom(); + + SelectedMods.Value = Enumerable.Empty(); + return base.OnExiting(next); } From 1c952e58cc45710bf63d0226972d71818b33e778 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 13:15:48 +0900 Subject: [PATCH 162/278] Fix testcase failures --- osu.Game/Tests/Visual/OsuTestCase.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 9dab981ed5..1a8403db40 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual [Cached] [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> SelectedMods = new Bindable>(); + protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); protected DependencyContainer Dependencies { get; private set; } @@ -38,12 +38,10 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - // This is the earliest we can get OsuGameBase, which is used by the dummy working beatmap to find textures - beatmap.Default = new DummyWorkingBeatmap(Dependencies.Get()); + beatmap.Default = new DummyWorkingBeatmap(parent.Get()); - return Dependencies; + return Dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); } protected OsuTestCase() From 4c571acd671a293dfbe3a6aee6963475bcbb67cc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 13:33:16 +0900 Subject: [PATCH 163/278] Reinstantiate mods for every player --- osu.Game/Screens/Play/Player.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bf2bbc58b8..d8e31b7ad6 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -69,6 +70,10 @@ namespace osu.Game.Screens.Play protected GameplayClockContainer GameplayClockContainer { get; private set; } + [Cached] + [Cached(Type = typeof(IBindable>))] + protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); + private readonly bool allowPause; private readonly bool showResults; @@ -88,6 +93,8 @@ namespace osu.Game.Screens.Play { this.api = api; + SelectedMods.Value = base.SelectedMods.Value.Select(m => m.CreateCopy()).ToArray(); + WorkingBeatmap working = loadBeatmap(); if (working == null) From d8ec1e73a3025c162e10cebbf8606af91c0ac88c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 13:50:54 +0900 Subject: [PATCH 164/278] Cleanup TestCasePlayerLoader --- .../Visual/Gameplay/TestCasePlayerLoader.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index 41d484e21f..aba689b241 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -2,10 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System.Threading; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Screens; -using osu.Game.Beatmaps; using osu.Game.Screens; using osu.Game.Screens.Play; @@ -21,23 +21,15 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.Add(stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }); } - [BackgroundDependencyLoader] - private void load(OsuGameBase game) + [Test] + public void TestLoadContinuation() { - Beatmap.Value = new DummyWorkingBeatmap(game); - AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player(false, false)))); - AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); - AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen()); - AddStep("exit loader", () => loader.Exit()); - AddUntilStep("wait for no longer alive", () => !loader.IsAlive); - AddStep("load slow dummy beatmap", () => { SlowLoadPlayer slow = null; From aa2c97b859eec9cc6778520a45b13bb5d1c21341 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 15:05:03 +0900 Subject: [PATCH 165/278] Add mod reinstantiation testcase --- .../Visual/Gameplay/TestCasePlayerLoader.cs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index aba689b241..fba4aca343 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -1,11 +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 System.Collections.Generic; +using System.Linq; using System.Threading; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Screens; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens; using osu.Game.Screens.Play; @@ -42,6 +47,81 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen()); } + [Test] + public void TestModReinstantiation() + { + TestPlayer player = null; + TestMod gameMod = null; + TestMod playerMod1 = null; + TestMod playerMod2 = null; + + AddStep("load player", () => + { + SelectedMods.Value = new[] { gameMod = new TestMod() }; + InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre); + stack.Push(new PlayerLoader(() => player = new TestPlayer())); + }); + + AddUntilStep("wait for player to become current", () => + { + if (player.IsCurrentScreen()) + { + playerMod1 = (TestMod)player.SelectedMods.Value.Single(); + return true; + } + + return false; + }); + + AddAssert("game mods not applied", () => gameMod.Applied == false); + AddAssert("player mods applied", () => playerMod1.Applied); + + AddStep("restart player", () => + { + player = null; + player.Restart(); + }); + + AddUntilStep("wait for player to become current", () => + { + if (player.IsCurrentScreen()) + { + playerMod2 = (TestMod)player.SelectedMods.Value.Single(); + return true; + } + + return false; + }); + + AddAssert("game mods not applied", () => gameMod.Applied == false); + AddAssert("player has different mods", () => playerMod1 != playerMod2); + AddAssert("player mods applied", () => playerMod2.Applied); + } + + private class TestMod : Mod, IApplicableToScoreProcessor + { + public override string Name => string.Empty; + public override string Acronym => string.Empty; + public override double ScoreMultiplier => 1; + + public bool Applied { get; private set; } + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + Applied = true; + } + } + + private class TestPlayer : Player + { + public new Bindable> SelectedMods => base.SelectedMods; + + public TestPlayer() + : base(false, false) + { + } + } + protected class SlowLoadPlayer : Player { public bool Ready; From 0603ed9ab755dc45c0d25822e4de2c5ec84c9721 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 9 Apr 2019 16:27:10 +0900 Subject: [PATCH 166/278] Fix post-merge errors --- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 1 + osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index ecdafb0fa2..27546fa424 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; 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.Game.Beatmaps; using osu.Game.Configuration; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index c0d9ecad3a..e70bf4c572 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -6,6 +6,7 @@ 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.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; From 4310f07a5cbba63eba921db02ed3e4ff9ce9498d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Apr 2019 12:03:57 +0900 Subject: [PATCH 167/278] Rename SelectedMods -> Mods --- .../TestCaseAutoJuiceStream.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs | 3 +-- .../TestCaseHitCircleHidden.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs | 3 +-- .../TestCaseSliderHidden.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestCaseSpinner.cs | 3 +-- .../TestCaseSpinnerHidden.cs | 2 +- .../Background/TestCaseBackgroundScreenBeatmap.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs | 2 +- .../Visual/SongSelect/TestCasePlaySongSelect.cs | 8 ++++---- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 6 +++--- osu.Game/Overlays/MusicController.cs | 6 +++--- osu.Game/Rulesets/UI/Playfield.cs | 4 ++-- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 4 ++-- osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 4 ++-- osu.Game/Screens/OsuScreenDependencies.cs | 10 +++++----- osu.Game/Screens/Play/Player.cs | 14 +++++++------- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- osu.Game/Screens/Select/MatchSongSelect.cs | 8 ++++---- osu.Game/Screens/Select/PlaySongSelect.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 10 +++++----- osu.Game/Tests/Visual/AllPlayersTestCase.cs | 2 +- osu.Game/Tests/Visual/OsuTestCase.cs | 2 +- osu.Game/Tests/Visual/PlayerTestCase.cs | 2 +- 26 files changed, 55 insertions(+), 58 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs index a696ba4e7e..0b20f34eb1 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Player CreatePlayer(Ruleset ruleset) { - SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); return base.CreatePlayer(ruleset); } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs index e1e854e8dc..31f3146046 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs @@ -30,7 +30,6 @@ namespace osu.Game.Rulesets.Osu.Tests protected override Container Content => content; private int depthIndex; - protected readonly List Mods = new List(); public TestCaseHitCircle() { @@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Tests Depth = depthIndex++ }; - foreach (var mod in Mods.OfType()) + foreach (var mod in Mods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); Add(drawable); diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs index 26d9b5ae91..7391c0f11a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Tests public TestCaseHitCircleHidden() { - Mods.Add(new OsuModHidden()); + Mods.Value = new[] { new OsuModHidden() }; } } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs index 35e8f3e17e..0f02050605 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs @@ -44,7 +44,6 @@ namespace osu.Game.Rulesets.Osu.Tests protected override Container Content => content; private int depthIndex; - protected readonly List Mods = new List(); public TestCaseSlider() { @@ -292,7 +291,7 @@ namespace osu.Game.Rulesets.Osu.Tests Depth = depthIndex++ }; - foreach (var mod in Mods.OfType()) + foreach (var mod in Mods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); drawable.OnNewResult += onNewResult; diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSliderHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSliderHidden.cs index ba5bd48c51..65a8005407 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSliderHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSliderHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Tests public TestCaseSliderHidden() { - Mods.Add(new OsuModHidden()); + Mods.Value = new[] { new OsuModHidden() }; } } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSpinner.cs index e8b534bba9..ab33d1e518 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSpinner.cs @@ -31,7 +31,6 @@ namespace osu.Game.Rulesets.Osu.Tests protected override Container Content => content; private int depthIndex; - protected readonly List Mods = new List(); public TestCaseSpinner() { @@ -57,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Tests Depth = depthIndex++ }; - foreach (var mod in Mods.OfType()) + foreach (var mod in Mods.Value.OfType()) mod.ApplyToDrawableHitObjects(new[] { drawable }); Add(drawable); diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSpinnerHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSpinnerHidden.cs index 6136ce1639..24e3bcb47b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSpinnerHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSpinnerHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Tests public TestCaseSpinnerHidden() { - Mods.Add(new OsuModHidden()); + Mods.Value = new[] { new OsuModHidden() }; } } } diff --git a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs index e3875421b1..283fd4c8b9 100644 --- a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs @@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Background AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddStep("Set default user settings", () => { - SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }); + Mods.Value = Mods.Value.Concat(new[] { new OsuModNoFail() }); songSelect.DimLevel.Value = 0.7f; songSelect.BlurLevel.Value = 0.4f; }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs index c930e77e9e..df48834e1f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); return new ScoreAccessiblePlayer(); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs index a70529b384..e89b361104 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs @@ -171,17 +171,17 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("change ruleset", () => { - SelectedMods.ValueChanged += onModChange; + Mods.ValueChanged += onModChange; songSelect.Ruleset.ValueChanged += onRulesetChange; Ruleset.Value = new TaikoRuleset().RulesetInfo; - SelectedMods.ValueChanged -= onModChange; + Mods.ValueChanged -= onModChange; songSelect.Ruleset.ValueChanged -= onRulesetChange; }); AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); - AddAssert("empty mods", () => !SelectedMods.Value.Any()); + AddAssert("empty mods", () => !Mods.Value.Any()); void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex--; @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.SongSelect private static int importId; private int getImportId() => ++importId; - private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => SelectedMods.Value = mods); + private void changeMods(params Mod[] mods) => AddStep($"change mods to {string.Join(", ", mods.Select(m => m.Acronym))}", () => Mods.Value = mods); private void changeRuleset(int id) => AddStep($"change ruleset to {id}", () => Ruleset.Value = rulesets.AvailableRulesets.First(r => r.ID == id)); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4d889677a5..0785c588e5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -113,7 +113,7 @@ namespace osu.Game // todo: move this to SongSelect once Screen has the ability to unsuspend. [Cached] [Cached(Type = typeof(IBindable>))] - private readonly Bindable> selectedMods = new Bindable>(Enumerable.Empty()); + private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); public OsuGame(string[] args = null) { @@ -294,7 +294,7 @@ namespace osu.Game { ruleset.Value = databasedScoreInfo.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); - selectedMods.Value = databasedScoreInfo.Mods; + mods.Value = databasedScoreInfo.Mods; menuScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore))); }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index aa41723ca6..9e97f4551a 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -42,19 +42,19 @@ namespace osu.Game.Overlays.Mods protected readonly FillFlowContainer ModSectionsContainer; - protected readonly Bindable> SelectedMods = new Bindable>(new Mod[] { }); + protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); protected readonly IBindable Ruleset = new Bindable(); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> selectedMods) + private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> mods) { LowMultiplierColour = colours.Red; HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; Ruleset.BindTo(ruleset); - if (selectedMods != null) SelectedMods.BindTo(selectedMods); + if (mods != null) SelectedMods.BindTo(mods); sampleOn = audio.Sample.Get(@"UI/check-on"); sampleOff = audio.Sample.Get(@"UI/check-off"); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 0ad4da2ce9..d9b669f753 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays private Bindable beatmap { get; set; } [Resolved] - private IBindable> selectedMods { get; set; } + private IBindable> mods { get; set; } /// /// Provide a source for the toolbar height. @@ -235,7 +235,7 @@ namespace osu.Game.Overlays { beatmap.BindValueChanged(beatmapChanged, true); beatmap.BindDisabledChanged(beatmapDisabledChanged, true); - selectedMods.BindValueChanged(_ => updateAudioAdjustments(), true); + mods.BindValueChanged(_ => updateAudioAdjustments(), true); base.LoadComplete(); } @@ -372,7 +372,7 @@ namespace osu.Game.Overlays track.ResetSpeedAdjustments(); - foreach (var mod in selectedMods.Value.OfType()) + foreach (var mod in mods.Value.OfType()) mod.ApplyToClock(track); } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 6ea565af44..c9a05dae2c 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.UI private IBindable beatmap { get; set; } [Resolved] - private IBindable> selectedMods { get; set; } + private IBindable> mods { get; set; } [BackgroundDependencyLoader] private void load() @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.UI base.Update(); if (beatmap != null) - foreach (var mod in selectedMods.Value) + foreach (var mod in mods.Value) if (mod is IUpdatableByPlayfield updatable) updatable.Update(this); } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 5f29044c76..aad571cf87 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Multi.Match { RoomManager?.PartRoom(); - SelectedMods.Value = Enumerable.Empty(); + Mods.Value = Enumerable.Empty(); return base.OnExiting(next); } @@ -193,7 +193,7 @@ namespace osu.Game.Screens.Multi.Match var localBeatmap = e.NewValue?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == e.NewValue.Beatmap.OnlineBeatmapID); Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - SelectedMods.Value = e.NewValue?.RequiredMods ?? Enumerable.Empty(); + Mods.Value = e.NewValue?.RequiredMods ?? Enumerable.Empty(); if (e.NewValue?.Ruleset != null) Ruleset.Value = e.NewValue.Ruleset; } diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 8ce68ac593..9692dc513d 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Play if (ruleset.Value.ID != playlistItem.Ruleset.ID) throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset"); - if (!playlistItem.RequiredMods.All(m => SelectedMods.Value.Contains(m))) + if (!playlistItem.RequiredMods.All(m => Mods.Value.Contains(m))) throw new InvalidOperationException("Current Mods do not match PlaylistItem's RequiredMods"); var req = new CreateRoomScoreRequest(roomId.Value ?? 0, playlistItem.ID); diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index bd7f326b50..d1e700cf92 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens public Bindable Ruleset { get; private set; } - public Bindable> SelectedMods { get; private set; } + public Bindable> Mods { get; private set; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { @@ -73,7 +73,7 @@ namespace osu.Game.Screens Beatmap = screenDependencies.Beatmap; Ruleset = screenDependencies.Ruleset; - SelectedMods = screenDependencies.SelectedMods; + Mods = screenDependencies.Mods; return base.CreateChildDependencies(screenDependencies); } diff --git a/osu.Game/Screens/OsuScreenDependencies.cs b/osu.Game/Screens/OsuScreenDependencies.cs index 9cc415f581..d7e1862c05 100644 --- a/osu.Game/Screens/OsuScreenDependencies.cs +++ b/osu.Game/Screens/OsuScreenDependencies.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens public Bindable Ruleset { get; } - public Bindable> SelectedMods { get; } + public Bindable> Mods { get; } public OsuScreenDependencies(bool requireLease, IReadOnlyDependencyContainer parent) : base(parent) @@ -31,15 +31,15 @@ namespace osu.Game.Screens if (Ruleset == null) Cache(Ruleset = parent.Get>().BeginLease(true)); - SelectedMods = parent.Get>>()?.GetBoundCopy(); - if (SelectedMods == null) - Cache(SelectedMods = parent.Get>>().BeginLease(true)); + Mods = parent.Get>>()?.GetBoundCopy(); + if (Mods == null) + Cache(Mods = parent.Get>>().BeginLease(true)); } else { Beatmap = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); Ruleset = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); - SelectedMods = (parent.Get>>() ?? parent.Get>>()).GetBoundCopy(); + Mods = (parent.Get>>() ?? parent.Get>>()).GetBoundCopy(); } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bf2bbc58b8..5add641404 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Play if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); - InternalChild = GameplayClockContainer = new GameplayClockContainer(working, SelectedMods.Value, DrawableRuleset.GameplayStartTime); + InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime); GameplayClockContainer.Children = new[] { @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Play }, // display the cursor above some HUD elements. DrawableRuleset.Cursor?.CreateProxy() ?? new Container(), - HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, SelectedMods.Value) + HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value) { HoldToQuit = { Action = performUserRequestedExit }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, @@ -170,7 +170,7 @@ namespace osu.Game.Screens.Play ScoreProcessor.AllJudged += onCompletion; ScoreProcessor.Failed += onFail; - foreach (var mod in SelectedMods.Value.OfType()) + foreach (var mod in Mods.Value.OfType()) mod.ApplyToScoreProcessor(ScoreProcessor); } @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Play try { - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(working, SelectedMods.Value); + DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(working, Mods.Value); } catch (BeatmapInvalidForRulesetException) { @@ -200,7 +200,7 @@ namespace osu.Game.Screens.Play // let's try again forcing the beatmap's ruleset. ruleset = beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); - DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(Beatmap.Value, SelectedMods.Value); + DrawableRuleset = rulesetInstance.CreateDrawableRulesetWith(Beatmap.Value, Mods.Value); } if (!DrawableRuleset.Objects.Any()) @@ -271,7 +271,7 @@ namespace osu.Game.Screens.Play { Beatmap = Beatmap.Value.BeatmapInfo, Ruleset = ruleset, - Mods = SelectedMods.Value.ToArray(), + Mods = Mods.Value.ToArray(), User = api.LocalUser.Value, }; @@ -325,7 +325,7 @@ namespace osu.Game.Screens.Play private bool onFail() { - if (SelectedMods.Value.OfType().Any(m => !m.AllowFail)) + if (Mods.Value.OfType().Any(m => !m.AllowFail)) return false; GameplayClockContainer.Stop(); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 70f5736786..2096f3f0f8 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - info = new BeatmapMetadataDisplay(Beatmap.Value, SelectedMods.Value) + info = new BeatmapMetadataDisplay(Beatmap.Value, Mods.Value) { Alpha = 0, Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 1011f6f32d..4468f5704f 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Select RulesetID = Ruleset.Value.ID ?? 0 }; - item.RequiredMods.AddRange(SelectedMods.Value); + item.RequiredMods.AddRange(Mods.Value); Selected?.Invoke(item); @@ -61,12 +61,12 @@ namespace osu.Game.Screens.Select { Ruleset.Value = CurrentItem.Value.Ruleset; Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap); - SelectedMods.Value = CurrentItem.Value.RequiredMods ?? Enumerable.Empty(); + Mods.Value = CurrentItem.Value.RequiredMods ?? Enumerable.Empty(); } Beatmap.Disabled = true; Ruleset.Disabled = true; - SelectedMods.Disabled = true; + Mods.Disabled = true; return false; } @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Select Beatmap.Disabled = false; Ruleset.Disabled = false; - SelectedMods.Disabled = false; + Mods.Disabled = false; } } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 340ceb6864..44e38edda8 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -52,10 +52,10 @@ namespace osu.Game.Screens.Select var auto = Ruleset.Value.CreateInstance().GetAutoplayMod(); var autoType = auto.GetType(); - var mods = SelectedMods.Value; + var mods = Mods.Value; if (mods.All(m => m.GetType() != autoType)) { - SelectedMods.Value = mods.Append(auto); + Mods.Value = mods.Append(auto); removeAutoModOnResume = true; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 2bb646750c..6ad5b54e65 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -85,7 +85,7 @@ namespace osu.Game.Screens.Select [Cached] [Cached(Type = typeof(IBindable>))] - private readonly Bindable> selectedMods = new Bindable>(Enumerable.Empty()); // Bound to the game's mods, but is not reset on exiting + private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); // Bound to the game's mods, but is not reset on exiting protected SongSelect() { @@ -219,7 +219,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins) { - selectedMods.BindTo(SelectedMods); + mods.BindTo(Mods); if (Footer != null) { @@ -394,7 +394,7 @@ namespace osu.Game.Screens.Select { Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); - selectedMods.Value = Enumerable.Empty(); + mods.Value = Enumerable.Empty(); decoupledRuleset.Value = ruleset; // force a filter before attempting to change the beatmap. @@ -529,8 +529,8 @@ namespace osu.Game.Screens.Select if (Beatmap.Value.Track != null) Beatmap.Value.Track.Looping = false; - selectedMods.UnbindAll(); - SelectedMods.Value = Enumerable.Empty(); + mods.UnbindAll(); + Mods.Value = Enumerable.Empty(); return false; } diff --git a/osu.Game/Tests/Visual/AllPlayersTestCase.cs b/osu.Game/Tests/Visual/AllPlayersTestCase.cs index 21955da6e9..af190ec7d5 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestCase.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestCase.cs @@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual var working = CreateWorkingBeatmap(beatmap, Clock); Beatmap.Value = working; - SelectedMods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; + Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; Player?.Exit(); Player = null; diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 1a8403db40..8ec440db8b 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual [Cached] [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); + protected readonly Bindable> Mods = new Bindable>(Enumerable.Empty()); protected DependencyContainer Dependencies { get; private set; } diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index 409e79b4a5..719b1d6892 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual Beatmap.Value = new TestWorkingBeatmap(beatmap, Clock); if (!AllowFail) - SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; + Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) }; Player = CreatePlayer(ruleset); LoadScreen(Player); From 7845d542e3b63d86c2c9364c14021bbd9c96a239 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Apr 2019 17:11:17 +0900 Subject: [PATCH 168/278] Cache mods as array in DrawableRuleset --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 11 +++++------ osu.Game/Rulesets/UI/Playfield.cs | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 0ab07de1ac..654f330a08 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -81,9 +81,8 @@ namespace osu.Game.Rulesets.UI /// /// The mods which are to be applied. /// - [Cached] - [Cached(typeof(IBindable>))] - private readonly Bindable> mods = new Bindable>(); + [Cached(typeof(IReadOnlyList))] + private readonly IReadOnlyList mods; private FrameStabilityContainer frameStabilityContainer; @@ -100,7 +99,7 @@ namespace osu.Game.Rulesets.UI if (workingBeatmap == null) throw new ArgumentException("Beatmap cannot be null.", nameof(workingBeatmap)); - this.mods.Value = mods; + this.mods = mods.ToArray(); RelativeSizeAxes = Axes.Both; @@ -160,7 +159,7 @@ namespace osu.Game.Rulesets.UI .WithChild(ResumeOverlay))); } - applyRulesetMods(mods.Value, config); + applyRulesetMods(mods, config); loadObjects(); } @@ -175,7 +174,7 @@ namespace osu.Game.Rulesets.UI Playfield.PostProcess(); - foreach (var mod in mods.Value.OfType()) + foreach (var mod in mods.OfType()) mod.ApplyToDrawableHitObjects(Playfield.HitObjectContainer.Objects); } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index c9a05dae2c..13689153f0 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.UI private IBindable beatmap { get; set; } [Resolved] - private IBindable> mods { get; set; } + private IReadOnlyList mods { get; set; } [BackgroundDependencyLoader] private void load() @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.UI base.Update(); if (beatmap != null) - foreach (var mod in mods.Value) + foreach (var mod in mods) if (mod is IUpdatableByPlayfield updatable) updatable.Update(this); } From 0222424aef8cf51e5f201633938880d8d756f25f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Apr 2019 17:13:12 +0900 Subject: [PATCH 169/278] Make mods IReadOnlyList gamewide Prevents potential multiple evaluations of enumerable. --- osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu.Tests/StackingTest.cs | 3 ++- osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs | 2 +- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs | 3 +-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 3 ++- .../Visual/Background/TestCaseBackgroundScreenBeatmap.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs | 3 ++- .../Visual/SongSelect/TestCasePlaySongSelect.cs | 2 +- osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 8 ++++---- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++-- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 6 +++--- .../Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- osu.Game/Screens/Multi/Match/Components/Header.cs | 3 +-- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 6 +++--- osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/OsuScreenDependencies.cs | 8 ++++---- osu.Game/Screens/Play/GameplayClockContainer.cs | 4 ++-- osu.Game/Screens/Play/HUD/ModDisplay.cs | 6 +++--- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 4 ++-- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 ++-- osu.Game/Screens/Select/MatchSongSelect.cs | 3 +-- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 8 ++++---- osu.Game/Tests/Visual/OsuTestCase.cs | 4 ++-- 44 files changed, 68 insertions(+), 68 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs index 0b20f34eb1..102afa9ca6 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return base.CreatePlayer(ruleset); } } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 544694fc8f..404766051f 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableCatchRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableCatchRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index 4b75b54d41..0324ba1d0b 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; diff --git a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs index 0bfbf38832..e5f379f608 100644 --- a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs +++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit { public new IScrollingInfo ScrollingInfo => base.ScrollingInfo; - public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index ebc94c86e2..5a8af60aab 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Edit public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns; - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) { DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 02a9b5ed30..36381294f5 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableManiaRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableManiaRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index 9d10657680..f592023300 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Bindable configDirection = new Bindable(); - public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { // Generate the bar lines diff --git a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs index 13c9985f47..e8b99e86f9 100644 --- a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.IO; using System.Linq; using System.Text; @@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Tests using (var reader = new StreamReader(stream)) { var beatmap = Decoder.GetDecoder(reader).Decode(reader); - var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Enumerable.Empty()); + var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty()); var objects = converted.HitObjects.ToList(); diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index 0c3050bfb4..bcb6099cfb 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit { public class DrawableOsuEditRuleset : DrawableOsuRuleset { - public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 9c4b6ee7aa..12e15be9b9 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuEditRuleset(ruleset, beatmap, mods); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 115271da85..40155cf8a9 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableOsuRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableOsuRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index c2954e1b3b..ba7241c165 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.UI { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; - public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableOsuRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs index c42faea9f9..9ceb1a9846 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -88,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, Height = 768, - Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap, Enumerable.Empty()) } + Children = new[] { drawableRuleset = new DrawableTaikoRuleset(new TaikoRuleset(), beatmap, Array.Empty()) } }); } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index cb53ec890b..f90894ff5d 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) => new DrawableTaikoRuleset(this, beatmap, mods); + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableTaikoRuleset(this, beatmap, mods); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 76bdd37ed3..adff869d26 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + public DrawableTaikoRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Left; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index e181130774..6738e0e7c2 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.IO; using NUnit.Framework; using osuTK; @@ -40,7 +41,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(6, working.BeatmapInfo.BeatmapVersion); Assert.AreEqual(6, working.Beatmap.BeatmapInfo.BeatmapVersion); - Assert.AreEqual(6, working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Enumerable.Empty()).BeatmapInfo.BeatmapVersion); + Assert.AreEqual(6, working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty()).BeatmapInfo.BeatmapVersion); } } diff --git a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs index 283fd4c8b9..81fab5b4b3 100644 --- a/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs +++ b/osu.Game.Tests/Visual/Background/TestCaseBackgroundScreenBeatmap.cs @@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.Background AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null); AddStep("Set default user settings", () => { - Mods.Value = Mods.Value.Concat(new[] { new OsuModNoFail() }); + Mods.Value = Mods.Value.Concat(new[] { new OsuModNoFail() }).ToArray(); songSelect.DimLevel.Value = 0.7f; songSelect.BlurLevel.Value = 0.4f; }); diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs index df48834e1f..624e5f08bd 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseAutoplay.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray(); return new ScoreAccessiblePlayer(); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs index 2a72dc8242..263070ab21 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseReplay.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.ComponentModel; using System.Linq; using osu.Game.Rulesets; @@ -16,7 +17,7 @@ namespace osu.Game.Tests.Visual.Gameplay { protected override Player CreatePlayer(Ruleset ruleset) { - var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Enumerable.Empty()); + var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Array.Empty()); return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod().CreateReplayScore(beatmap)); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs index e89b361104..7e33f6ce02 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestCasePlaySongSelect.cs @@ -183,7 +183,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); AddAssert("empty mods", () => !Mods.Value.Any()); - void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; + void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex--; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs index aab44f7d92..fd003c7ea2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs @@ -253,7 +253,7 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestModSelectOverlay : ModSelectOverlay { - public new Bindable> SelectedMods => base.SelectedMods; + public new Bindable> SelectedMods => base.SelectedMods; public ModButton GetModButton(Mod mod) { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 3e6033da9c..58463d2219 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -52,7 +52,7 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods) + public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) { throw new NotImplementedException(); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ec0a76b52b..8989785dcd 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -75,7 +75,7 @@ namespace osu.Game.Beatmaps /// The to create a playable for. /// The converted . /// If could not be converted to . - public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IEnumerable mods) + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) { var rulesetInstance = ruleset.CreateInstance(); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0785c588e5..30f98aa1ce 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -112,8 +112,8 @@ namespace osu.Game // todo: move this to SongSelect once Screen has the ability to unsuspend. [Cached] - [Cached(Type = typeof(IBindable>))] - private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); + [Cached(typeof(IBindable>))] + private readonly Bindable> mods = new Bindable>(Array.Empty()); public OsuGame(string[] args = null) { diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 9e97f4551a..97769fe5aa 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -42,12 +42,12 @@ namespace osu.Game.Overlays.Mods protected readonly FillFlowContainer ModSectionsContainer; - protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); + protected readonly Bindable> SelectedMods = new Bindable>(Array.Empty()); protected readonly IBindable Ruleset = new Bindable(); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> mods) + private void load(OsuColour colours, IBindable ruleset, AudioManager audio, Bindable> mods) { LowMultiplierColour = colours.Red; HighMultiplierColour = colours.Green; @@ -87,14 +87,14 @@ namespace osu.Game.Overlays.Mods // attempt to re-select any already selected mods. // this may be the first time we are receiving the ruleset, in which case they will still match. - selectedModsChanged(new ValueChangedEvent>(SelectedMods.Value, SelectedMods.Value)); + selectedModsChanged(new ValueChangedEvent>(SelectedMods.Value, SelectedMods.Value)); // write the mods back to the SelectedMods bindable in the case a change was not applicable. // this generally isn't required as the previous line will perform deselection; just here for safety. refreshSelectedMods(); } - private void selectedModsChanged(ValueChangedEvent> e) + private void selectedModsChanged(ValueChangedEvent> e) { foreach (ModSection section in ModSectionsContainer.Children) section.SelectTypes(e.NewValue.Select(m => m.GetType()).ToList()); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d9b669f753..c250d3b62a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays private Bindable beatmap { get; set; } [Resolved] - private IBindable> mods { get; set; } + private IBindable> mods { get; set; } /// /// Provide a source for the toolbar height. diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index e181051737..14f7665e05 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Difficulty /// public Mod[] CreateDifficultyAdjustmentModCombinations() { - return createDifficultyAdjustmentModCombinations(Enumerable.Empty(), DifficultyAdjustmentMods).ToArray(); + return createDifficultyAdjustmentModCombinations(Array.Empty(), DifficultyAdjustmentMods).ToArray(); IEnumerable createDifficultyAdjustmentModCombinations(IEnumerable currentSet, Mod[] adjustmentSet, int currentSetCount = 0, int adjustmentSetStart = 0) { diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 5219cb9581..38ec09535d 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -186,8 +186,8 @@ namespace osu.Game.Rulesets.Edit } internal override DrawableEditRuleset CreateDrawableRuleset() - => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Enumerable.Empty())); + => new DrawableEditRuleset(CreateDrawableRuleset(Ruleset, Beatmap.Value, Array.Empty())); - protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods); + protected abstract DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 90fe25accf..3521c17b23 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets /// The beatmap to create the hit renderer for. /// Unable to successfully load the beatmap to be usable with this ruleset. /// - public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IEnumerable mods); + public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods); /// /// Creates a to convert a to one that is applicable for this . diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 654f330a08..2866e81682 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.UI /// /// The ruleset being represented. /// The beatmap to create the hit renderer for. - protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IEnumerable mods) + protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IReadOnlyList mods) : base(ruleset) { if (workingBeatmap == null) @@ -257,7 +257,7 @@ namespace osu.Game.Rulesets.UI /// Applies the active mods to the Beatmap. /// /// - private void applyBeatmapMods(IEnumerable mods) + private void applyBeatmapMods(IReadOnlyList mods) { if (mods == null) return; @@ -270,7 +270,7 @@ namespace osu.Game.Rulesets.UI /// Applies the active mods to this DrawableRuleset. /// /// - private void applyRulesetMods(IEnumerable mods, OsuConfigManager config) + private void applyRulesetMods(IReadOnlyList mods, OsuConfigManager config) { if (mods == null) return; diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 2bb98dd679..dbe8d8c299 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.UI.Scrolling [Cached(Type = typeof(IScrollingInfo))] private readonly LocalScrollingInfo scrollingInfo; - protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IEnumerable mods) + protected DrawableScrollingRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) { scrollingInfo = new LocalScrollingInfo(); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index e1592532a3..2a6074882d 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -110,7 +109,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => modDisplay.Current.Value = item.NewValue?.RequiredMods ?? Enumerable.Empty(), true); + CurrentItem.BindValueChanged(item => modDisplay.Current.Value = item.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(), true); beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index aad571cf87..6271693a6a 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.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 System.Linq; +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Multi.Match { RoomManager?.PartRoom(); - Mods.Value = Enumerable.Empty(); + Mods.Value = Array.Empty(); return base.OnExiting(next); } @@ -193,7 +193,7 @@ namespace osu.Game.Screens.Multi.Match var localBeatmap = e.NewValue?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == e.NewValue.Beatmap.OnlineBeatmapID); Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Mods.Value = e.NewValue?.RequiredMods ?? Enumerable.Empty(); + Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); if (e.NewValue?.Ruleset != null) Ruleset.Value = e.NewValue.Ruleset; } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index d1e700cf92..c1a822c75c 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens public Bindable Ruleset { get; private set; } - public Bindable> Mods { get; private set; } + public Bindable> Mods { get; private set; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { diff --git a/osu.Game/Screens/OsuScreenDependencies.cs b/osu.Game/Screens/OsuScreenDependencies.cs index d7e1862c05..4167faba83 100644 --- a/osu.Game/Screens/OsuScreenDependencies.cs +++ b/osu.Game/Screens/OsuScreenDependencies.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens public Bindable Ruleset { get; } - public Bindable> Mods { get; } + public Bindable> Mods { get; } public OsuScreenDependencies(bool requireLease, IReadOnlyDependencyContainer parent) : base(parent) @@ -31,15 +31,15 @@ namespace osu.Game.Screens if (Ruleset == null) Cache(Ruleset = parent.Get>().BeginLease(true)); - Mods = parent.Get>>()?.GetBoundCopy(); + Mods = parent.Get>>()?.GetBoundCopy(); if (Mods == null) - Cache(Mods = parent.Get>>().BeginLease(true)); + Cache(Mods = parent.Get>>().BeginLease(true)); } else { Beatmap = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); Ruleset = (parent.Get>() ?? parent.Get>()).GetBoundCopy(); - Mods = (parent.Get>>() ?? parent.Get>>()).GetBoundCopy(); + Mods = (parent.Get>>() ?? parent.Get>>()).GetBoundCopy(); } } } diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 2b18ef5ecd..29974b728e 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play public class GameplayClockContainer : Container { private readonly WorkingBeatmap beatmap; - private readonly IEnumerable mods; + private readonly IReadOnlyList mods; /// /// The original source (usually a 's track). @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Play private readonly FramedOffsetClock platformOffsetClock; - public GameplayClockContainer(WorkingBeatmap beatmap, IEnumerable mods, double gameplayStartTime) + public GameplayClockContainer(WorkingBeatmap beatmap, IReadOnlyList mods, double gameplayStartTime) { this.beatmap = beatmap; this.mods = mods; diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 2c1293833f..878d2b7c38 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -18,15 +18,15 @@ using osu.Game.Graphics; namespace osu.Game.Screens.Play.HUD { - public class ModDisplay : Container, IHasCurrentValue> + public class ModDisplay : Container, IHasCurrentValue> { private const int fade_duration = 1000; public bool DisplayUnrankedText = true; - private readonly Bindable> current = new Bindable>(); + private readonly Bindable> current = new Bindable>(); - public Bindable> Current + public Bindable> Current { get => current; set diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index aa4375f652..3c1b33297a 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Play public Action RequestSeek; - public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IEnumerable mods) + public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList mods) { RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 2096f3f0f8..1c558eae2e 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -301,7 +301,7 @@ namespace osu.Game.Screens.Play } private readonly WorkingBeatmap beatmap; - private readonly IEnumerable mods; + private readonly IReadOnlyList mods; private LoadingAnimation loading; private Sprite backgroundSprite; private ModDisplay modDisplay; @@ -323,7 +323,7 @@ namespace osu.Game.Screens.Play } } - public BeatmapMetadataDisplay(WorkingBeatmap beatmap, IEnumerable mods) + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, IReadOnlyList mods) { this.beatmap = beatmap; this.mods = mods; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 03cf767062..51f87dcc6d 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -310,12 +310,12 @@ namespace osu.Game.Screens.Select try { // Try to get the beatmap with the user's ruleset - playableBeatmap = beatmap.GetPlayableBeatmap(ruleset, Enumerable.Empty()); + playableBeatmap = beatmap.GetPlayableBeatmap(ruleset, Array.Empty()); } catch (BeatmapInvalidForRulesetException) { // Can't be converted to the user's ruleset, so use the beatmap's own ruleset - playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset, Enumerable.Empty()); + playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset, Array.Empty()); } labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s))); diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 4468f5704f..c5fa9e2396 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -61,7 +60,7 @@ namespace osu.Game.Screens.Select { Ruleset.Value = CurrentItem.Value.Ruleset; Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap); - Mods.Value = CurrentItem.Value.RequiredMods ?? Enumerable.Empty(); + Mods.Value = CurrentItem.Value.RequiredMods?.ToArray() ?? Array.Empty(); } Beatmap.Disabled = true; diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 44e38edda8..bf4f898323 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select var mods = Mods.Value; if (mods.All(m => m.GetType() != autoType)) { - Mods.Value = mods.Append(auto); + Mods.Value = mods.Append(auto).ToArray(); removeAutoModOnResume = true; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6ad5b54e65..a78238c584 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -84,8 +84,8 @@ namespace osu.Game.Screens.Select private readonly Bindable decoupledRuleset = new Bindable(); [Cached] - [Cached(Type = typeof(IBindable>))] - private readonly Bindable> mods = new Bindable>(Enumerable.Empty()); // Bound to the game's mods, but is not reset on exiting + [Cached(Type = typeof(IBindable>))] + private readonly Bindable> mods = new Bindable>(Array.Empty()); // Bound to the game's mods, but is not reset on exiting protected SongSelect() { @@ -394,7 +394,7 @@ namespace osu.Game.Screens.Select { Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); - mods.Value = Enumerable.Empty(); + mods.Value = Array.Empty(); decoupledRuleset.Value = ruleset; // force a filter before attempting to change the beatmap. @@ -530,7 +530,7 @@ namespace osu.Game.Screens.Select Beatmap.Value.Track.Looping = false; mods.UnbindAll(); - Mods.Value = Enumerable.Empty(); + Mods.Value = Array.Empty(); return false; } diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 8ec440db8b..c08a6a4bcb 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -28,8 +28,8 @@ namespace osu.Game.Tests.Visual protected readonly Bindable Ruleset = new Bindable(); [Cached] - [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> Mods = new Bindable>(Enumerable.Empty()); + [Cached(Type = typeof(IBindable>))] + protected readonly Bindable> Mods = new Bindable>(Array.Empty()); protected DependencyContainer Dependencies { get; private set; } From 1db2d49696a8cc33b54968e6ec6ab3dbfe5ece70 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Apr 2019 17:54:57 +0900 Subject: [PATCH 170/278] Fix testcases --- .../ManiaPlacementBlueprintTestCase.cs | 6 ++++++ osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs | 4 ++++ osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs | 5 +++++ .../Visual/Gameplay/TestCaseScrollingHitObjects.cs | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs b/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs index 13bbe87513..9ad22498a9 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -8,6 +10,7 @@ using osu.Framework.Timing; using osu.Game.Rulesets.Mania.Edit; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Tests.Visual; @@ -21,6 +24,9 @@ namespace osu.Game.Rulesets.Mania.Tests { private readonly Column column; + [Cached(typeof(IReadOnlyList))] + private IReadOnlyList mods { get; set; } = Array.Empty(); + protected ManiaPlacementBlueprintTestCase() { Add(column = new Column(0) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs index b14f999f61..d46b661eea 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mania.UI.Components; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Tests.Visual; using osuTK; @@ -31,6 +32,9 @@ namespace osu.Game.Rulesets.Mania.Tests typeof(ColumnHitObjectArea) }; + [Cached(typeof(IReadOnlyList))] + private IReadOnlyList mods { get; set; } = Array.Empty(); + private readonly List columns = new List(); public TestCaseColumn() diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs index ac430037e4..9a7a3d1c5c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -13,6 +14,7 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Tests.Visual; using osuTK; @@ -24,6 +26,9 @@ namespace osu.Game.Rulesets.Mania.Tests { private const int columns = 4; + [Cached(typeof(IReadOnlyList))] + private IReadOnlyList mods { get; set; } = Array.Empty(); + private readonly List stages = new List(); private FillFlowContainer fill; diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseScrollingHitObjects.cs index c99a4bb89b..3cfc5ac7c8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseScrollingHitObjects.cs @@ -4,11 +4,13 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Configuration; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; @@ -23,6 +25,9 @@ namespace osu.Game.Tests.Visual.Gameplay { public override IReadOnlyList RequiredTypes => new[] { typeof(Playfield) }; + [Cached(typeof(IReadOnlyList))] + private IReadOnlyList mods { get; set; } = Array.Empty(); + private readonly ScrollingTestContainer[] scrollContainers = new ScrollingTestContainer[4]; private readonly TestPlayfield[] playfields = new TestPlayfield[4]; From ac2eabc9bfb8bf7c5d52b5b8a1f97ca37fc1c585 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Apr 2019 17:47:00 +0900 Subject: [PATCH 171/278] Fix replay rewinding not respecting 60fps playback --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index deec2b8eac..c307520aca 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.UI { if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) { - newProposedTime = manualClock.Rate > 0 + newProposedTime = newProposedTime > manualClock.CurrentTime ? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time) : Math.Max(newProposedTime, manualClock.CurrentTime - sixty_frame_time); } From b684cd49e6fdd0233f91be155c1bdd182a76ddf7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 Apr 2019 22:51:57 +0800 Subject: [PATCH 172/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 74ed9f91dd..1fcbe7c4c1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9fff64c61c..831f33f0b8 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 5a3d6a02585b2d3b97e5846359e28a7b317cf6e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 16:11:59 +0900 Subject: [PATCH 173/278] Fix post-merge errors --- osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs | 8 ++++---- osu.Game/Screens/Play/Player.cs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index fba4aca343..f58c0d35b3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("load player", () => { - SelectedMods.Value = new[] { gameMod = new TestMod() }; + Mods.Value = new[] { gameMod = new TestMod() }; InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre); stack.Push(new PlayerLoader(() => player = new TestPlayer())); }); @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.Gameplay { if (player.IsCurrentScreen()) { - playerMod1 = (TestMod)player.SelectedMods.Value.Single(); + playerMod1 = (TestMod)player.Mods.Value.Single(); return true; } @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Gameplay { if (player.IsCurrentScreen()) { - playerMod2 = (TestMod)player.SelectedMods.Value.Single(); + playerMod2 = (TestMod)player.Mods.Value.Single(); return true; } @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestPlayer : Player { - public new Bindable> SelectedMods => base.SelectedMods; + public new Bindable> Mods => base.Mods; public TestPlayer() : base(false, false) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f8b3efb781..f833aa2bb7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -71,8 +71,8 @@ namespace osu.Game.Screens.Play protected GameplayClockContainer GameplayClockContainer { get; private set; } [Cached] - [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> SelectedMods = new Bindable>(Enumerable.Empty()); + [Cached(Type = typeof(IBindable>))] + protected readonly Bindable> Mods = new Bindable>(Array.Empty()); private readonly bool allowPause; private readonly bool showResults; @@ -93,7 +93,7 @@ namespace osu.Game.Screens.Play { this.api = api; - SelectedMods.Value = base.SelectedMods.Value.Select(m => m.CreateCopy()).ToArray(); + Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); WorkingBeatmap working = loadBeatmap(); From 9f92b3a8ba503940bbd559388149812086a4504f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 16:34:53 +0900 Subject: [PATCH 174/278] Add xmldoc --- osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index 5ebdb7d45d..f139040abd 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -60,6 +60,9 @@ namespace osu.Game.Graphics.Containers startPosition = null; } + /// + /// Stops the logo assigned in from tracking the facade's position. + /// public void StopTracking() { if (Logo != null) From 3a1587fa53b53ce5490032469d8e19fce34d3f47 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 16:40:47 +0900 Subject: [PATCH 175/278] Throw exception when not relatively positioned --- osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index f139040abd..ddf257776f 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -92,12 +92,15 @@ namespace osu.Game.Graphics.Containers if (Logo == null) return; + if (Logo.RelativePositionAxes != Axes.Both) + throw new InvalidOperationException($"Tracking logo must have {nameof(RelativePositionAxes)} = Axes.Both"); + // Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale. ((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X)); var localPos = ComputeLogoTrackingPosition(); - if (LogoFacade.Parent != null && Logo.Position != localPos && Logo.RelativePositionAxes == Axes.Both) + if (LogoFacade.Parent != null && Logo.Position != localPos) { // If this is our first update since tracking has started, initialize our starting values for interpolation if (startTime == null || startPosition == null) From 4106da24303cf0289293d0d87ccc16fc4aee0b93 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 16:41:20 +0900 Subject: [PATCH 176/278] Rename facade + cleanup usage --- .../Graphics/Containers/LogoTrackingContainer.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index ddf257776f..fb23038dde 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -15,22 +15,19 @@ namespace osu.Game.Graphics.Containers /// public class LogoTrackingContainer : Container { - public Facade LogoFacade { get; } + public Facade LogoFacade => facade; protected OsuLogo Logo { get; private set; } + private readonly InternalFacade facade = new InternalFacade(); + private Easing easing; private Vector2? startPosition; private double? startTime; private double duration; - public LogoTrackingContainer() - { - LogoFacade = new ExposedFacade(); - } - /// - /// Assign the logo that should track the Facade's position, as well as how it should transform to its initial position. + /// Assign the logo that should track the facade's position, as well as how it should transform to its initial position. /// /// The instance of the logo to be used for tracking. /// The scale of the facade. Does not actually affect the logo itself. @@ -96,7 +93,7 @@ namespace osu.Game.Graphics.Containers throw new InvalidOperationException($"Tracking logo must have {nameof(RelativePositionAxes)} = Axes.Both"); // Account for the scale of the actual OsuLogo, as SizeForFlow only accounts for the sprite scale. - ((ExposedFacade)LogoFacade).SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X)); + facade.SetSize(new Vector2(Logo.SizeForFlow * Logo.Scale.X)); var localPos = ComputeLogoTrackingPosition(); @@ -133,7 +130,7 @@ namespace osu.Game.Graphics.Containers base.Dispose(isDisposing); } - private class ExposedFacade : Facade + private class InternalFacade : Facade { public void SetSize(Vector2 size) { From 897bfa60db361b01682be36b55640ed3bf4a4d9f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 17:02:47 +0900 Subject: [PATCH 177/278] Fix tracking position during 150ms state change delay --- osu.Game/Screens/Menu/ButtonArea.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/ButtonArea.cs b/osu.Game/Screens/Menu/ButtonArea.cs index d6e1aef63c..eada1e0777 100644 --- a/osu.Game/Screens/Menu/ButtonArea.cs +++ b/osu.Game/Screens/Menu/ButtonArea.cs @@ -32,6 +32,7 @@ namespace osu.Game.Screens.Menu RelativeSizeAxes = Axes.X, Size = new Vector2(1, BUTTON_AREA_HEIGHT), Alpha = 0, + AlwaysPresent = true, // Always needs to be present for correct tracking on initial -> toplevel state change Children = new Drawable[] { buttonAreaBackground = new ButtonAreaBackground(), From 106e77c3d7794ab923380cbeb2cbe72c7b289741 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 17:15:23 +0900 Subject: [PATCH 178/278] Cleanup testcase --- .../TestCaseLogoTrackingContainer.cs | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 8b70a34c85..088a46d5e4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -35,7 +35,6 @@ namespace osu.Game.Tests.Visual.UserInterface }; private OsuLogo logo; - private readonly Bindable uiScale = new Bindable(); private TestLogoTrackingContainer trackingContainer; private Container transferContainer; private Box visualBox; @@ -45,13 +44,6 @@ namespace osu.Game.Tests.Visual.UserInterface private const float visual_box_size = 72; - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - config.BindWith(OsuSetting.UIScale, uiScale); - AddSliderStep("Adjust scale", 0.8f, 1.5f, 1f, v => uiScale.Value = v); - } - [SetUpSteps] public void SetUpSteps() { @@ -69,7 +61,7 @@ namespace osu.Game.Tests.Visual.UserInterface /// Check if the logo is still tracking the facade. /// [Test] - public void MoveFacadeTest() + public void TestMoveFacade() { AddToggleStep("Toggle move continuously", b => randomPositions = b); AddStep("Add tracking containers", addFacadeContainers); @@ -82,7 +74,7 @@ namespace osu.Game.Tests.Visual.UserInterface /// Check if the facade is removed from the container, the logo stops tracking. /// [Test] - public void RemoveFacadeTest() + public void TestRemoveFacade() { AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", moveLogoFacade); @@ -95,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface /// Check if the facade gets added to a new container, tracking starts on the new facade. /// [Test] - public void TransferFacadeTest() + public void TestTransferFacade() { AddStep("Add tracking containers", addFacadeContainers); AddStep("Move facade to random position", moveLogoFacade); @@ -106,6 +98,7 @@ namespace osu.Game.Tests.Visual.UserInterface transferContainerBox.Colour = Color4.Tomato; moveLogoFacade(); }); + waitForMove(); AddAssert("Logo is tracking", () => trackingContainer.IsLogoTracking); } @@ -114,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface /// Add a facade to a flow container, move the logo to the center of the screen, then start tracking on the facade. /// [Test] - public void FlowContainerTest() + public void TestFlowContainer() { FillFlowContainer flowContainer; @@ -188,14 +181,16 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void SetFacadeSizeTest() + public void TestSetFacadeSize() { bool failed = false; + AddStep("Set up scenario", () => { failed = false; addFacadeContainers(); }); + AddStep("Try setting facade size", () => { try @@ -208,14 +203,16 @@ namespace osu.Game.Tests.Visual.UserInterface failed = true; } }); + AddAssert("Exception thrown", () => failed); } [Test] - public void SetMultipleContainersTest() + public void TestSetMultipleContainers() { bool failed = false; LogoTrackingContainer newContainer = new LogoTrackingContainer(); + AddStep("Set up scenario", () => { failed = false; @@ -223,6 +220,7 @@ namespace osu.Game.Tests.Visual.UserInterface addFacadeContainers(); moveLogoFacade(); }); + AddStep("Try tracking new container", () => { try @@ -235,6 +233,7 @@ namespace osu.Game.Tests.Visual.UserInterface failed = true; } }); + AddAssert("Exception thrown", () => failed); } From c145ce2d005ac723d1625fab276d23cc4384855d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 17:19:55 +0900 Subject: [PATCH 179/278] Remove usings --- .../Visual/UserInterface/TestCaseLogoTrackingContainer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs index 088a46d5e4..e45e2e24da 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseLogoTrackingContainer.cs @@ -4,15 +4,12 @@ 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.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.MathUtils; using osu.Framework.Testing; -using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; From 12b6bc48bd780a20b563f7c45cd9c8e5662e7c19 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 17 Apr 2019 17:24:09 +0900 Subject: [PATCH 180/278] Use .With() wherever possible --- osu.Game/Screens/Menu/ButtonSystem.cs | 3 +-- osu.Game/Screens/Play/PlayerLoader.cs | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f6778691bf..519fadb34b 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -101,11 +101,10 @@ namespace osu.Game.Screens.Menu { VisibleState = ButtonSystemState.Play, }, - logoTrackingContainer.LogoFacade + logoTrackingContainer.LogoFacade.With(d => d.Scale = new Vector2(0.74f)) }); buttonArea.Flow.CentreTarget = logoTrackingContainer.LogoFacade; - logoTrackingContainer.LogoFacade.Scale = new Vector2(0.74f); } [Resolved(CanBeNull = true)] diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 7ff214c607..6a55fe278b 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -351,9 +351,6 @@ namespace osu.Game.Screens.Play { var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); - facade.Anchor = Anchor.TopCentre; - facade.Origin = Anchor.TopCentre; - AutoSizeAxes = Axes.Both; Children = new Drawable[] { @@ -365,7 +362,11 @@ namespace osu.Game.Screens.Play Direction = FillDirection.Vertical, Children = new[] { - facade, + facade.With(d => + { + d.Anchor = Anchor.TopCentre; + d.Origin = Anchor.TopCentre; + }), new OsuSpriteText { Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)), From 9d6912a6920848036a617f241c4c4ff154e04149 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 18 Apr 2019 21:23:40 +0800 Subject: [PATCH 181/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1fcbe7c4c1..2b7ded6d8c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 831f33f0b8..958191d708 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From c8d760b555b52265f0cf2dc3f3ec3832ead211e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 18 Apr 2019 21:33:29 +0800 Subject: [PATCH 182/278] Attempt using previous appveyor image --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1f485485da..4dcaa7b45e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 +image: Previous Visual Studio 2017 test: off install: - cmd: git submodule update --init --recursive --depth=5 From 7a0320d39e29c66824a04ef7b6e06a4aaa35cfe9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 19 Apr 2019 00:01:26 +0800 Subject: [PATCH 183/278] Increase diagnostic level --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 4dcaa7b45e..51e946219f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,8 @@ clone_depth: 1 version: '{branch}-{build}' -image: Previous Visual Studio 2017 +image: Visual Studio 2017 test: off install: - cmd: git submodule update --init --recursive --depth=5 build_script: - - cmd: PowerShell -Version 2.0 .\build.ps1 + - cmd: PowerShell -Version 2.0 .\build.ps1 -Verbosity Diagnostic From 6502e26d09020a3ee564b40e74e0fa937aca70ea Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 19 Apr 2019 16:21:15 +0900 Subject: [PATCH 184/278] Add draw size invalidation to ZoomableScrollContainer --- .../Components/Timeline/ZoomableScrollContainer.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 1e94a20dc7..f41b3cddc0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -92,13 +92,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - protected override void Update() - { - base.Update(); - - zoomedContent.Width = DrawWidth * currentZoom; - } - protected override bool OnScroll(ScrollEvent e) { if (e.IsPrecise) @@ -169,6 +162,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; d.currentZoom = newZoom; + + d.zoomedContent.Width = d.DrawWidth * d.currentZoom; + // Temporarily here to make sure ScrollTo gets the correct DrawSize for scrollable area. + // TODO: Make sure draw size gets invalidated properly on the framework side, and remove this once it is. + d.Invalidate(Invalidation.DrawSize); d.ScrollTo(targetOffset, false); } From d3920d652d82b1d7603bec9e94ba9f9500d9879e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 19 Apr 2019 12:44:57 +0900 Subject: [PATCH 185/278] Fix loader animation test case --- osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs index df12e14891..eb275cbceb 100644 --- a/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs +++ b/osu.Game.Tests/Visual/Menus/TestCaseLoaderAnimation.cs @@ -23,7 +23,11 @@ namespace osu.Game.Tests.Visual.Menus public TestCaseLoaderAnimation() { - Child = logo = new OsuLogo { Depth = float.MinValue }; + Child = logo = new OsuLogo + { + Alpha = 0, + Depth = float.MinValue + }; } [Test] @@ -39,7 +43,7 @@ namespace osu.Game.Tests.Visual.Menus LoadScreen(loader); }); - AddAssert("loaded", () => + AddUntilStep("loaded", () => { logoVisible = loader.Logo?.Alpha > 0; return loader.Logo != null && loader.ScreenLoaded; From 489929d25ce7eb0907ee8a848a5aa3094c22bde1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 19 Apr 2019 19:45:17 +0900 Subject: [PATCH 186/278] Fix PlayerLoader testcase being completely broken --- .../Visual/Gameplay/TestCasePlayerLoader.cs | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index f58c0d35b3..1f0a97cc58 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -10,21 +10,25 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Screens; using osu.Game.Screens.Play; +using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Gameplay { public class TestCasePlayerLoader : ManualInputManagerTestCase { private PlayerLoader loader; - private readonly OsuScreenStack stack; + private OsuScreenStack stack; - public TestCasePlayerLoader() + [SetUp] + public void Setup() => Schedule(() => { - InputManager.Add(stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }); - } + InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; + Beatmap.Value = new TestWorkingBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), Clock); + }); [Test] public void TestLoadContinuation() @@ -33,8 +37,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for current", () => loader.IsCurrentScreen()); AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen()); - AddStep("exit loader", () => loader.Exit()); - AddUntilStep("wait for no longer alive", () => !loader.IsAlive); AddStep("load slow dummy beatmap", () => { SlowLoadPlayer slow = null; @@ -58,41 +60,25 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("load player", () => { Mods.Value = new[] { gameMod = new TestMod() }; - InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre); - stack.Push(new PlayerLoader(() => player = new TestPlayer())); - }); - - AddUntilStep("wait for player to become current", () => - { - if (player.IsCurrentScreen()) - { - playerMod1 = (TestMod)player.Mods.Value.Single(); - return true; - } - - return false; + stack.Push(loader = new PlayerLoader(() => player = new TestPlayer())); }); + AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen()); + AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); + AddUntilStep("wait for player to be current", () => player.IsCurrentScreen()); + AddStep("retrieve mods", () => playerMod1 = (TestMod)player.Mods.Value.Single()); AddAssert("game mods not applied", () => gameMod.Applied == false); AddAssert("player mods applied", () => playerMod1.Applied); AddStep("restart player", () => { + var lastPlayer = player; player = null; - player.Restart(); - }); - - AddUntilStep("wait for player to become current", () => - { - if (player.IsCurrentScreen()) - { - playerMod2 = (TestMod)player.Mods.Value.Single(); - return true; - } - - return false; + lastPlayer.Restart(); }); + AddUntilStep("wait for player to be current", () => player.IsCurrentScreen()); + AddStep("retrieve mods", () => playerMod2 = (TestMod)player.Mods.Value.Single()); AddAssert("game mods not applied", () => gameMod.Applied == false); AddAssert("player has different mods", () => playerMod1 != playerMod2); AddAssert("player mods applied", () => playerMod2.Applied); From 5989cf284904b5affa224656412a9b687f1f880d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 19 Apr 2019 20:39:25 +0900 Subject: [PATCH 187/278] Revert "Increase diagnostic level" This reverts commit 7a0320d39e29c66824a04ef7b6e06a4aaa35cfe9. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 51e946219f..4dcaa7b45e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,8 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 +image: Previous Visual Studio 2017 test: off install: - cmd: git submodule update --init --recursive --depth=5 build_script: - - cmd: PowerShell -Version 2.0 .\build.ps1 -Verbosity Diagnostic + - cmd: PowerShell -Version 2.0 .\build.ps1 From 4cf234295c67e05bc598299e70212bf55f7ceb9f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 19 Apr 2019 21:27:24 +0900 Subject: [PATCH 188/278] Fix appveyor temporarily --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1f485485da..4dcaa7b45e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 +image: Previous Visual Studio 2017 test: off install: - cmd: git submodule update --init --recursive --depth=5 From 8e485f32835d6d0c72b9e04d52c3ab1b42879b8c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 20 Apr 2019 06:41:09 +0300 Subject: [PATCH 189/278] Fix issue --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index f3c7939a94..9e3f28918c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -12,6 +12,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osuTK; using osuTK.Graphics; @@ -40,6 +41,10 @@ namespace osu.Game.Rulesets.Osu.Mods { scoreProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); }; } + + public ScoreRank AdjustRank(ScoreRank rank) + { + } /// /// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency. From 59da78b0d4fd31a3df67b77d973fc66fbc0a94f7 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sat, 20 Apr 2019 06:44:59 +0300 Subject: [PATCH 190/278] nothing. --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 9e3f28918c..f3c7939a94 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -12,7 +12,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Scoring; using osuTK; using osuTK.Graphics; @@ -41,10 +40,6 @@ namespace osu.Game.Rulesets.Osu.Mods { scoreProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); }; } - - public ScoreRank AdjustRank(ScoreRank rank) - { - } /// /// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency. From 73da4236391df7209c476ff769faf2a480e8f20b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 15:58:19 +0300 Subject: [PATCH 191/278] Adjust rank --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0fddb19a6c..4a1eba9c5e 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -95,6 +95,11 @@ namespace osu.Game.Rulesets.Scoring /// protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; + /// + /// Used by specific mods to adjust . + /// + public bool AdjustRank { get; set; } + protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; @@ -104,9 +109,9 @@ namespace osu.Game.Rulesets.Scoring private ScoreRank rankFrom(double acc) { if (acc == 1) - return ScoreRank.X; + return (AdjustRank ? ScoreRank.XH : ScoreRank.X); if (acc > 0.95) - return ScoreRank.S; + return (AdjustRank ? ScoreRank.SH : ScoreRank.S); if (acc > 0.9) return ScoreRank.A; if (acc > 0.8) From 4e07975e7ca88c49d4c4fa83206bc27d254e7456 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 15:58:40 +0300 Subject: [PATCH 192/278] Ranks must be adjusted in Hidden Mod --- osu.Game/Rulesets/Mods/ModHidden.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index c7e3f0a78f..744da30f0a 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -8,10 +8,11 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mods { - public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects + public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects, IApplicableToScoreProcessor { public override string Name => "Hidden"; public override string Acronym => "HD"; @@ -31,6 +32,11 @@ namespace osu.Game.Rulesets.Mods foreach (var d in drawables.Skip(IncreaseFirstObjectVisibility.Value ? 1 : 0)) d.ApplyCustomUpdateState += ApplyHiddenState; } + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + scoreProcessor.AdjustRank = true; + } protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { From 77614189c978e4bffa18b4dee16dbfa90351944c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 17:48:50 +0300 Subject: [PATCH 193/278] Make AdjustRank Bindable --- osu.Game/Rulesets/Mods/ModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 744da30f0a..4c4177a779 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mods public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - scoreProcessor.AdjustRank = true; + scoreProcessor.AdjustRank.Value = true; } protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) From b200142afb174e4c16a64403cb23575ab3692fd3 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 17:55:01 +0300 Subject: [PATCH 194/278] Make AdjustRank Bindable and fix issue --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 4a1eba9c5e..617e643d41 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -98,20 +98,21 @@ namespace osu.Game.Rulesets.Scoring /// /// Used by specific mods to adjust . /// - public bool AdjustRank { get; set; } + public BindableBool AdjustRank = new BindableBool(); protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; Accuracy.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; + AdjustRank.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; // Update rank immediately if AdjustRank was changed } private ScoreRank rankFrom(double acc) { if (acc == 1) - return (AdjustRank ? ScoreRank.XH : ScoreRank.X); + return (AdjustRank.Value ? ScoreRank.XH : ScoreRank.X); if (acc > 0.95) - return (AdjustRank ? ScoreRank.SH : ScoreRank.S); + return (AdjustRank.Value ? ScoreRank.SH : ScoreRank.S); if (acc > 0.9) return ScoreRank.A; if (acc > 0.8) @@ -128,6 +129,7 @@ namespace osu.Game.Rulesets.Scoring /// Whether to store the current state of the for future use. protected virtual void Reset(bool storeResults) { + AdjustRank.Value = false; TotalScore.Value = 0; Accuracy.Value = 1; Health.Value = 1; From c5bf01cc5ccaf8a53f57fce21cc1fb16cf6cfc0b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 18:05:52 +0300 Subject: [PATCH 195/278] Fix issue --- osu.Game/Rulesets/Mods/ModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 4c4177a779..b36b2362ca 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mods foreach (var d in drawables.Skip(IncreaseFirstObjectVisibility.Value ? 1 : 0)) d.ApplyCustomUpdateState += ApplyHiddenState; } - + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { scoreProcessor.AdjustRank.Value = true; From cff319e0d8cd22d12f7e44a4754cca2a2f8051ec Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 21 Apr 2019 18:12:50 +0300 Subject: [PATCH 196/278] Fix issue --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 617e643d41..e60ca70969 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Scoring protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; /// - /// Used by specific mods to adjust . + /// Used by specific mods to adjust . /// public BindableBool AdjustRank = new BindableBool(); From 732c38fa794a81ab3c2b2e8be8a9abec8f189f89 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 10:45:56 +0900 Subject: [PATCH 197/278] Update framework again --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2b7ded6d8c..a45cac2cb6 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 958191d708..70edc01821 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 8ffb2f4224d5ba340fa6e42dd3518edbd938df2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 10:55:01 +0900 Subject: [PATCH 198/278] Remove black box blocking some visual tests from being visible --- osu.Game/Tests/Visual/AllPlayersTestCase.cs | 9 --------- osu.Game/Tests/Visual/PlayerTestCase.cs | 15 --------------- 2 files changed, 24 deletions(-) diff --git a/osu.Game/Tests/Visual/AllPlayersTestCase.cs b/osu.Game/Tests/Visual/AllPlayersTestCase.cs index af190ec7d5..3e1f408a16 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestCase.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestCase.cs @@ -3,7 +3,6 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Graphics.Shapes; using osu.Framework.Screens; using osu.Framework.Timing; using osu.Game.Beatmaps; @@ -11,7 +10,6 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; using osu.Game.Tests.Beatmaps; -using osuTK.Graphics; namespace osu.Game.Tests.Visual { @@ -26,13 +24,6 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - Add(new Box - { - RelativeSizeAxes = Framework.Graphics.Axes.Both, - Colour = Color4.Black, - Depth = int.MaxValue - }); - foreach (var r in rulesets.AvailableRulesets) { Player p = null; diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index 719b1d6892..d308b86b5a 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -2,16 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; using osu.Game.Tests.Beatmaps; -using osuTK.Graphics; namespace osu.Game.Tests.Visual { @@ -26,17 +22,6 @@ namespace osu.Game.Tests.Visual this.ruleset = ruleset; } - [BackgroundDependencyLoader] - private void load() - { - Add(new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Depth = int.MaxValue - }); - } - [SetUpSteps] public void SetUpSteps() { From 26f0b2a4fe65342757a52476367b6ae432b10b40 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 06:12:41 +0300 Subject: [PATCH 199/278] Remove bindable Bad usage --- osu.Game/Rulesets/Mods/ModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index b36b2362ca..389edb5a35 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mods public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - scoreProcessor.AdjustRank.Value = true; + scoreProcessor.AdjustRank = true; } protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) From de542ca20251951df7dea4cd449018aa03b2c29d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 06:14:14 +0300 Subject: [PATCH 200/278] Remove bindable and use property --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index e60ca70969..c37b5d189f 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -95,24 +95,29 @@ namespace osu.Game.Rulesets.Scoring /// protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; + private bool adjustRank = false; + /// /// Used by specific mods to adjust . /// - public BindableBool AdjustRank = new BindableBool(); + public bool AdjustRank + { + get { return adjustRank; } + set { adjustRank = value; Rank.Value = rankFrom(Accuracy.Value); } // Update rank immediately if AdjustRank was changed + } protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; Accuracy.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; - AdjustRank.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; // Update rank immediately if AdjustRank was changed } private ScoreRank rankFrom(double acc) { if (acc == 1) - return (AdjustRank.Value ? ScoreRank.XH : ScoreRank.X); + return (adjustRank ? ScoreRank.XH : ScoreRank.X); if (acc > 0.95) - return (AdjustRank.Value ? ScoreRank.SH : ScoreRank.S); + return (adjustRank ? ScoreRank.SH : ScoreRank.S); if (acc > 0.9) return ScoreRank.A; if (acc > 0.8) @@ -129,7 +134,6 @@ namespace osu.Game.Rulesets.Scoring /// Whether to store the current state of the for future use. protected virtual void Reset(bool storeResults) { - AdjustRank.Value = false; TotalScore.Value = 0; Accuracy.Value = 1; Health.Value = 1; @@ -137,6 +141,7 @@ namespace osu.Game.Rulesets.Scoring Rank.Value = ScoreRank.X; HighestCombo.Value = 0; + AdjustRank = false; HasFailed = false; } From c784bc4418c9908099a1ecc08fb6194140743224 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 06:15:37 +0300 Subject: [PATCH 201/278] Remove whitespaces --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index c37b5d189f..e563d3a848 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Scoring protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; private bool adjustRank = false; - + /// /// Used by specific mods to adjust . /// From a47f5040af2b157f58aeabc6ac9bbae97d09b0e2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 13:58:05 +0900 Subject: [PATCH 202/278] Improve waveform graph testing --- .../Visual/Editor/TestCaseWaveform.cs | 79 +++++++++++++------ 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs b/osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs index c35e8741c1..ce6ca08a61 100644 --- a/osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs +++ b/osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs @@ -3,12 +3,13 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; -using osuTK; using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editor @@ -16,35 +17,38 @@ namespace osu.Game.Tests.Visual.Editor [TestFixture] public class TestCaseWaveform : OsuTestCase { + private WorkingBeatmap waveformBeatmap; + [BackgroundDependencyLoader] private void load() { - Beatmap.Value = new WaveformTestBeatmap(); + waveformBeatmap = new WaveformTestBeatmap(); + } - FillFlowContainer flow; - Child = flow = new FillFlowContainer + [TestCase(1f)] + [TestCase(1f / 2)] + [TestCase(1f / 4)] + [TestCase(1f / 8)] + [TestCase(1f / 16)] + [TestCase(0f)] + public void TestResolution(float resolution) + { + TestWaveformGraph graph = null; + + AddStep("add graph", () => { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10), - }; - - for (int i = 1; i <= 16; i *= 2) - { - var newDisplay = new WaveformGraph - { - RelativeSizeAxes = Axes.Both, - Resolution = 1f / i, - Waveform = Beatmap.Value.Waveform, - }; - - flow.Add(new Container + Child = new Container { RelativeSizeAxes = Axes.X, Height = 100, Children = new Drawable[] { - newDisplay, + graph = new TestWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Resolution = resolution, + Waveform = waveformBeatmap.Waveform, + }, new Container { Anchor = Anchor.Centre, @@ -62,13 +66,42 @@ namespace osu.Game.Tests.Visual.Editor { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {1f / i:0.00}" + Text = $"Resolution: {resolution:0.00}" } } } } - }); - } + }; + }); + + AddUntilStep("wait for load", () => graph.ResampledWaveform != null); + } + + [Test] + public void TestDefaultBeatmap() + { + TestWaveformGraph graph = null; + + AddStep("add graph", () => + { + Child = new Container + { + RelativeSizeAxes = Axes.X, + Height = 100, + Child = graph = new TestWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Waveform = new DummyWorkingBeatmap().Waveform, + }, + }; + }); + + AddUntilStep("wait for load", () => graph.ResampledWaveform != null); + } + + public class TestWaveformGraph : WaveformGraph + { + public new Waveform ResampledWaveform => base.ResampledWaveform; } } } From 7a385e56ecd0089689ce63d145eb5fbd44a8f5da Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 09:58:29 +0300 Subject: [PATCH 203/278] Fix AppVeyor Errors --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index e563d3a848..99178409fb 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -95,15 +95,20 @@ namespace osu.Game.Rulesets.Scoring /// protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; - private bool adjustRank = false; + private bool adjustRank; /// /// Used by specific mods to adjust . /// public bool AdjustRank { - get { return adjustRank; } - set { adjustRank = value; Rank.Value = rankFrom(Accuracy.Value); } // Update rank immediately if AdjustRank was changed + get => return adjustRank; + + set + { + adjustRank = value; + Rank.Value = rankFrom(Accuracy.Value); // Update rank immediately if AdjustRank was changed + } } protected ScoreProcessor() From 64429aa96877c96ca67f53d6a95b0b98085fe425 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 09:59:51 +0300 Subject: [PATCH 204/278] Fix AppVeyor Errors --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 99178409fb..fc7e8746b7 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Scoring public bool AdjustRank { get => return adjustRank; - + set { adjustRank = value; From 903093503041d6fd3f2061615cbc2cda56239b9d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 10:07:45 +0300 Subject: [PATCH 205/278] Fix AppVeyor Errors --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index fc7e8746b7..b3e1beed04 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -104,8 +104,8 @@ namespace osu.Game.Rulesets.Scoring { get => return adjustRank; - set - { + set + { adjustRank = value; Rank.Value = rankFrom(Accuracy.Value); // Update rank immediately if AdjustRank was changed } From cfb3c38c3a086dd1d892fe471ca1c80da1e1f710 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Mon, 22 Apr 2019 10:14:19 +0300 Subject: [PATCH 206/278] Fix. --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b3e1beed04..b1cd78dde6 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Scoring /// public bool AdjustRank { - get => return adjustRank; + get => adjustRank; set { From fbb4e9df044b2e6d3d911de3846cc6140dd7ef6f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 16:51:38 +0900 Subject: [PATCH 207/278] Implement hp at base ScoreProcessor --- osu.Game/Rulesets/Judgements/Judgement.cs | 5 +++++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index e14eedd3dc..f07f76a2b8 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -31,6 +31,11 @@ namespace osu.Game.Rulesets.Judgements /// public int MaxNumericResult => NumericResultFor(MaxResult); + /// + /// The health increase for the maximum achievable result. + /// + public double MaxHealthIncrease => HealthIncreaseFor(MaxResult); + /// /// Retrieves the numeric score representation of a . /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0fddb19a6c..1a682080bf 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -206,6 +206,9 @@ namespace osu.Game.Rulesets.Scoring private double baseScore; private double bonusScore; + private double rollingHp; + private double rollingMaxHp; + protected ScoreProcessor() { } @@ -332,6 +335,9 @@ namespace osu.Game.Rulesets.Scoring baseScore += result.Judgement.NumericResultFor(result); rollingMaxBaseScore += result.Judgement.MaxNumericResult; } + + rollingHp += HpFactorFor(result.Judgement, result.Type) * result.Judgement.HealthIncreaseFor(result); + rollingMaxHp += HpFactorFor(result.Judgement, result.Judgement.MaxResult) * result.Judgement.MaxHealthIncrease; } /// @@ -356,8 +362,13 @@ namespace osu.Game.Rulesets.Scoring baseScore -= result.Judgement.NumericResultFor(result); rollingMaxBaseScore -= result.Judgement.MaxNumericResult; } + + rollingHp -= HpFactorFor(result.Judgement, result.Type) * result.Judgement.HealthIncreaseFor(result); + rollingMaxHp -= HpFactorFor(result.Judgement, result.Judgement.MaxResult) * result.Judgement.MaxHealthIncrease; } + protected virtual double HpFactorFor(Judgement judgement, HitResult result) => 1; + private void updateScore() { if (rollingMaxBaseScore != 0) From d7919544fe8e5e6f78fb04834c44fbb7ff721b89 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 16:59:14 +0900 Subject: [PATCH 208/278] Implement approximate hp increase for catch --- .../Judgements/CatchBananaJudgement.cs | 2 +- .../Judgements/CatchDropletJudgement.cs | 4 ++-- .../Judgements/CatchJudgement.cs | 4 ++-- .../Judgements/CatchTinyDropletJudgement.cs | 2 +- .../Scoring/CatchScoreProcessor.cs | 20 ++++++++----------- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 4e64753a65..31f825c3ef 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Judgements default: return 0; case HitResult.Perfect: - return 8; + return 0.08; } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index 2598dee156..f03897d611 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -23,9 +23,9 @@ namespace osu.Game.Rulesets.Catch.Judgements switch (result) { default: - return 0; + return base.HealthIncreaseFor(result); case HitResult.Perfect: - return 7; + return 0.07; } } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index 5d7ef04dd2..abc38fe258 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -27,9 +27,9 @@ namespace osu.Game.Rulesets.Catch.Judgements switch (result) { default: - return 0; + return -0.02; case HitResult.Perfect: - return 10.2; + return 0.01; } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs index b8c51b7b60..bd1a74bc14 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Judgements default: return 0; case HitResult.Perfect: - return 4; + return 0.004; } } } diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index af614f95d0..40585f2054 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Judgements; @@ -27,20 +26,17 @@ namespace osu.Game.Rulesets.Catch.Scoring hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate; } - private const double harshness = 0.01; - - protected override void ApplyResult(JudgementResult result) + protected override double HpFactorFor(Judgement judgement, HitResult result) { - base.ApplyResult(result); - - if (result.Type == HitResult.Miss) + switch (result) { - if (!result.Judgement.IsBonus) - Health.Value -= hpDrainRate * (harshness * 2); - return; + case HitResult.Miss when judgement.IsBonus: + return 0; + case HitResult.Miss: + return hpDrainRate; + default: + return 10 - hpDrainRate; // Award less HP as drain rate is increased } - - Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness; } public override HitWindows CreateHitWindows() => new CatchHitWindows(); From 4c5f41e40f1646df96c8fe1b87cafbfe5e775749 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 17:04:18 +0900 Subject: [PATCH 209/278] Implement hp increase for mania --- .../Judgements/HoldNoteTickJudgement.cs | 11 ++++++ .../Judgements/ManiaJudgement.cs | 21 ++++++++++ .../Scoring/ManiaScoreProcessor.cs | 38 +------------------ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 015eb1310e..48c2eb547b 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -10,5 +10,16 @@ namespace osu.Game.Rulesets.Mania.Judgements public override bool AffectsCombo => false; protected override int NumericResultFor(HitResult result) => 20; + + protected override double HealthIncreaseFor(HitResult result) + { + switch (result) + { + case HitResult.Miss: + return 0; + default: + return 0.040; + } + } } } diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs index b6fb37f054..0548dc9eed 100644 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs @@ -25,5 +25,26 @@ namespace osu.Game.Rulesets.Mania.Judgements return 300; } } + + protected override double HealthIncreaseFor(HitResult result) + { + switch (result) + { + case HitResult.Miss: + return -0.125; + case HitResult.Meh: + return 0.005; + case HitResult.Ok: + return 0.010; + case HitResult.Good: + return 0.035; + case HitResult.Great: + return 0.055; + case HitResult.Perfect: + return 0.065; + default: + return 0; + } + } } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 5c914d8eac..75a73614f0 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -122,42 +122,8 @@ namespace osu.Game.Rulesets.Mania.Scoring } } - protected override void ApplyResult(JudgementResult result) - { - base.ApplyResult(result); - - bool isTick = result.Judgement is HoldNoteTickJudgement; - - if (isTick) - { - if (result.IsHit) - Health.Value += hpMultiplier * hp_increase_tick; - } - else - { - switch (result.Type) - { - case HitResult.Miss: - Health.Value += hpMissMultiplier * hp_increase_miss; - break; - case HitResult.Meh: - Health.Value += hpMultiplier * hp_increase_bad; - break; - case HitResult.Ok: - Health.Value += hpMultiplier * hp_increase_ok; - break; - case HitResult.Good: - Health.Value += hpMultiplier * hp_increase_good; - break; - case HitResult.Great: - Health.Value += hpMultiplier * hp_increase_great; - break; - case HitResult.Perfect: - Health.Value += hpMultiplier * hp_increase_perfect; - break; - } - } - } + protected override double HpFactorFor(Judgement judgement, HitResult result) + => result == HitResult.Miss ? hpMissMultiplier : hpMultiplier; public override HitWindows CreateHitWindows() => new ManiaHitWindows(); } From b59f23d0944a5aa512c2bf3096d4ef7390f32e72 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 17:04:46 +0900 Subject: [PATCH 210/278] Implement hp increase for taiko --- .../Scoring/TaikoScoreProcessor.cs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 442cca49f8..a0055a93aa 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -46,19 +46,8 @@ namespace osu.Game.Rulesets.Taiko.Scoring hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120); } - protected override void ApplyResult(JudgementResult result) - { - base.ApplyResult(result); - - double hpIncrease = result.Judgement.HealthIncreaseFor(result); - - if (result.Type == HitResult.Miss) - hpIncrease *= hpMissMultiplier; - else - hpIncrease *= hpMultiplier; - - Health.Value += hpIncrease; - } + protected override double HpFactorFor(Judgement judgement, HitResult result) + => result == HitResult.Miss ? hpMissMultiplier : hpMultiplier; protected override void Reset(bool storeResults) { From 034643b8356bf2325d207ec0aab91179f402f3c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 17:06:01 +0900 Subject: [PATCH 211/278] Fix pause tests --- osu.Game/Rulesets/UI/Playfield.cs | 5 +++++ osu.Game/Screens/Play/GameplayClockContainer.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 13689153f0..a99c16a610 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -68,7 +68,12 @@ namespace osu.Game.Rulesets.UI { Cursor = CreateCursor(); if (Cursor != null) + { + // initial showing of the cursor will be handed by MenuCursorContainer (via DrawableRuleset's IProvideCursor implementation). + Cursor.Hide(); + AddInternal(Cursor); + } } /// diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 29974b728e..3654dc679c 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Play { // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time // This accounts for the audio clock source potentially taking time to enter a completely stopped state - adjustableClock.Seek(adjustableClock.CurrentTime); + adjustableClock.Seek(GameplayClock.CurrentTime); adjustableClock.Start(); IsPaused.Value = false; } From b3c496d72cb6d3a381098f357edcfd940c12a8ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 17:06:40 +0900 Subject: [PATCH 212/278] Remove delay on entering player --- osu.Game/Screens/Play/GameplayClockContainer.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 3654dc679c..2d1ba3f2ab 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -110,11 +110,8 @@ namespace osu.Game.Screens.Play adjustableClock.ChangeSource(sourceClock); updateRate(); - this.Delay(750).Schedule(() => - { - if (!IsPaused.Value) - Start(); - }); + if (!IsPaused.Value) + Start(); }); }); } From 78c844e25930af377c3c28162c58551d03c374b8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 17:24:22 +0900 Subject: [PATCH 213/278] Make catch provide some HP at DrainRate=10 --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 40585f2054..13c5028b23 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Scoring case HitResult.Miss: return hpDrainRate; default: - return 10 - hpDrainRate; // Award less HP as drain rate is increased + return 10.2 - hpDrainRate; // Award less HP as drain rate is increased } } From 144e6012dc333153c7e41ad37df544a23ea4b827 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 17:24:42 +0900 Subject: [PATCH 214/278] Implement hp increase for osu! --- .../Judgements/OsuJudgement.cs | 15 +++++++++++ .../Scoring/OsuScoreProcessor.cs | 25 ++++++++++--------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs index 81fedf9f4a..7a98c5003d 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs @@ -24,5 +24,20 @@ namespace osu.Game.Rulesets.Osu.Judgements return 300; } } + + protected override double HealthIncreaseFor(HitResult result) + { + switch (result) + { + case HitResult.Miss: + return -0.02; + case HitResult.Meh: + case HitResult.Good: + case HitResult.Great: + return 0.01; + default: + return 0; + } + } } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 2c8bf11016..a4975ef3b3 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -47,28 +47,29 @@ namespace osu.Game.Rulesets.Osu.Scoring if (result.Type != HitResult.None) comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1; + } - switch (result.Type) + protected override double HpFactorFor(Judgement judgement, HitResult result) + { + switch (result) { case HitResult.Great: - Health.Value += (10.2 - hpDrainRate) * harshness; - break; + return 10.2 - hpDrainRate; case HitResult.Good: - Health.Value += (8 - hpDrainRate) * harshness; - break; + return 8 - hpDrainRate; case HitResult.Meh: - Health.Value += (4 - hpDrainRate) * harshness; - break; + return 4 - hpDrainRate; - /*case HitResult.SliderTick: - Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01; - break;*/ + // case HitResult.SliderTick: + // return Math.Max(7 - hpDrainRate, 0) * 0.01; case HitResult.Miss: - Health.Value -= hpDrainRate * (harshness * 2); - break; + return hpDrainRate; + + default: + return 0; } } From 4edb17a88a9ac82ac06fb2c7a172e4ad4bc0dc2c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 17:51:43 +0900 Subject: [PATCH 215/278] Make hp work + cleanup --- .../Scoring/CatchScoreProcessor.cs | 6 +-- .../Scoring/ManiaScoreProcessor.cs | 44 +------------------ .../Scoring/OsuScoreProcessor.cs | 6 +-- .../Scoring/TaikoScoreProcessor.cs | 4 +- .../Rulesets/Judgements/JudgementResult.cs | 5 +++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 13 ++---- 6 files changed, 17 insertions(+), 61 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 13c5028b23..778a7426aa 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -26,12 +26,10 @@ namespace osu.Game.Rulesets.Catch.Scoring hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate; } - protected override double HpFactorFor(Judgement judgement, HitResult result) + protected override double HpFactorFor(JudgementResult result) { - switch (result) + switch (result.Type) { - case HitResult.Miss when judgement.IsBonus: - return 0; case HitResult.Miss: return hpDrainRate; default: diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 75a73614f0..ee4618e5c2 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -3,7 +3,6 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; @@ -28,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private const double hp_multiplier_max = 1; - /// - /// The default BAD hit HP increase. - /// - private const double hp_increase_bad = 0.005; - - /// - /// The default OK hit HP increase. - /// - private const double hp_increase_ok = 0.010; - - /// - /// The default GOOD hit HP increase. - /// - private const double hp_increase_good = 0.035; - - /// - /// The default tick hit HP increase. - /// - private const double hp_increase_tick = 0.040; - - /// - /// The default GREAT hit HP increase. - /// - private const double hp_increase_great = 0.055; - - /// - /// The default PERFECT hit HP increase. - /// - private const double hp_increase_perfect = 0.065; - /// /// The MISS HP multiplier at OD = 0. /// @@ -73,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private const double hp_multiplier_miss_max = 1; - /// - /// The default MISS HP increase. - /// - private const double hp_increase_miss = -0.125; - /// /// The MISS HP multiplier. This is multiplied to the miss hp increase. /// @@ -88,10 +52,6 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private double hpMultiplier = 1; - public ManiaScoreProcessor() - { - } - public ManiaScoreProcessor(DrawableRuleset drawableRuleset) : base(drawableRuleset) { @@ -122,8 +82,8 @@ namespace osu.Game.Rulesets.Mania.Scoring } } - protected override double HpFactorFor(Judgement judgement, HitResult result) - => result == HitResult.Miss ? hpMissMultiplier : hpMultiplier; + protected override double HpFactorFor(JudgementResult result) + => result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier; public override HitWindows CreateHitWindows() => new ManiaHitWindows(); } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index a4975ef3b3..2162663539 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Osu.Scoring comboResultCounts.Clear(); } - private const double harshness = 0.01; - protected override void ApplyResult(JudgementResult result) { base.ApplyResult(result); @@ -49,9 +47,9 @@ namespace osu.Game.Rulesets.Osu.Scoring comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1; } - protected override double HpFactorFor(Judgement judgement, HitResult result) + protected override double HpFactorFor(JudgementResult result) { - switch (result) + switch (result.Type) { case HitResult.Great: return 10.2 - hpDrainRate; diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index a0055a93aa..b2b866db4b 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -46,8 +46,8 @@ namespace osu.Game.Rulesets.Taiko.Scoring hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120); } - protected override double HpFactorFor(Judgement judgement, HitResult result) - => result == HitResult.Miss ? hpMissMultiplier : hpMultiplier; + protected override double HpFactorFor(JudgementResult result) + => result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier; protected override void Reset(bool storeResults) { diff --git a/osu.Game/Rulesets/Judgements/JudgementResult.cs b/osu.Game/Rulesets/Judgements/JudgementResult.cs index d4ef5750b1..195fe316ac 100644 --- a/osu.Game/Rulesets/Judgements/JudgementResult.cs +++ b/osu.Game/Rulesets/Judgements/JudgementResult.cs @@ -37,6 +37,11 @@ namespace osu.Game.Rulesets.Judgements /// public int HighestComboAtJudgement { get; internal set; } + /// + /// The health prior to this occurring. + /// + public double HealthAtJudgement { get; internal set; } + /// /// Whether a miss or hit occurred. /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 1a682080bf..429aa620f6 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -206,9 +206,6 @@ namespace osu.Game.Rulesets.Scoring private double baseScore; private double bonusScore; - private double rollingHp; - private double rollingMaxHp; - protected ScoreProcessor() { } @@ -304,6 +301,7 @@ namespace osu.Game.Rulesets.Scoring { result.ComboAtJudgement = Combo.Value; result.HighestComboAtJudgement = HighestCombo.Value; + result.HealthAtJudgement = Health.Value; JudgedHits++; @@ -336,8 +334,7 @@ namespace osu.Game.Rulesets.Scoring rollingMaxBaseScore += result.Judgement.MaxNumericResult; } - rollingHp += HpFactorFor(result.Judgement, result.Type) * result.Judgement.HealthIncreaseFor(result); - rollingMaxHp += HpFactorFor(result.Judgement, result.Judgement.MaxResult) * result.Judgement.MaxHealthIncrease; + Health.Value += HpFactorFor(result) * result.Judgement.HealthIncreaseFor(result); } /// @@ -349,6 +346,7 @@ namespace osu.Game.Rulesets.Scoring { Combo.Value = result.ComboAtJudgement; HighestCombo.Value = result.HighestComboAtJudgement; + Health.Value = result.HealthAtJudgement; JudgedHits--; @@ -362,12 +360,9 @@ namespace osu.Game.Rulesets.Scoring baseScore -= result.Judgement.NumericResultFor(result); rollingMaxBaseScore -= result.Judgement.MaxNumericResult; } - - rollingHp -= HpFactorFor(result.Judgement, result.Type) * result.Judgement.HealthIncreaseFor(result); - rollingMaxHp -= HpFactorFor(result.Judgement, result.Judgement.MaxResult) * result.Judgement.MaxHealthIncrease; } - protected virtual double HpFactorFor(Judgement judgement, HitResult result) => 1; + protected virtual double HpFactorFor(JudgementResult result) => 1; private void updateScore() { From 910b9df2d54b93e28c6e729807337d9a14f161bf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 18:02:57 +0900 Subject: [PATCH 216/278] Fix catch awarding too much hp --- osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs | 2 +- osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 31f825c3ef..5835e746b9 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Judgements default: return 0; case HitResult.Perfect: - return 0.08; + return 0.008; } } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index f03897d611..679691fcd6 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Judgements default: return base.HealthIncreaseFor(result); case HitResult.Perfect: - return 0.07; + return 0.007; } } } From aeae759fcd5b9949815b2bba02a799e9d6c277e8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 18:08:15 +0900 Subject: [PATCH 217/278] Rename method + add xmldoc --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 2 +- osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs | 2 +- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 +- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 9 +++++++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 778a7426aa..0d0ca6506c 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Scoring hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate; } - protected override double HpFactorFor(JudgementResult result) + protected override double HealthAdjustmentFactorFor(JudgementResult result) { switch (result.Type) { diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index ee4618e5c2..5caf08fb1e 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Scoring } } - protected override double HpFactorFor(JudgementResult result) + protected override double HealthAdjustmentFactorFor(JudgementResult result) => result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier; public override HitWindows CreateHitWindows() => new ManiaHitWindows(); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 2162663539..cf0565c6da 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Scoring comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1; } - protected override double HpFactorFor(JudgementResult result) + protected override double HealthAdjustmentFactorFor(JudgementResult result) { switch (result.Type) { diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index b2b866db4b..68ddf2db19 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120); } - protected override double HpFactorFor(JudgementResult result) + protected override double HealthAdjustmentFactorFor(JudgementResult result) => result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier; protected override void Reset(bool storeResults) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 429aa620f6..ba71e1e9b2 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -334,7 +334,7 @@ namespace osu.Game.Rulesets.Scoring rollingMaxBaseScore += result.Judgement.MaxNumericResult; } - Health.Value += HpFactorFor(result) * result.Judgement.HealthIncreaseFor(result); + Health.Value += HealthAdjustmentFactorFor(result) * result.Judgement.HealthIncreaseFor(result); } /// @@ -362,7 +362,12 @@ namespace osu.Game.Rulesets.Scoring } } - protected virtual double HpFactorFor(JudgementResult result) => 1; + /// + /// An adjustment factor which is multiplied into the health increase provided by a . + /// + /// The for which the adjustment should apply. + /// The adjustment factor. + protected virtual double HealthAdjustmentFactorFor(JudgementResult result) => 1; private void updateScore() { From 908eee9942653eabd72e68a3a60b93f7ec35cccd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 17:06:01 +0900 Subject: [PATCH 218/278] Fix pause tests --- osu.Game/Rulesets/UI/Playfield.cs | 5 +++++ osu.Game/Screens/Play/GameplayClockContainer.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 13689153f0..a99c16a610 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -68,7 +68,12 @@ namespace osu.Game.Rulesets.UI { Cursor = CreateCursor(); if (Cursor != null) + { + // initial showing of the cursor will be handed by MenuCursorContainer (via DrawableRuleset's IProvideCursor implementation). + Cursor.Hide(); + AddInternal(Cursor); + } } /// diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 29974b728e..3654dc679c 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Play { // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time // This accounts for the audio clock source potentially taking time to enter a completely stopped state - adjustableClock.Seek(adjustableClock.CurrentTime); + adjustableClock.Seek(GameplayClock.CurrentTime); adjustableClock.Start(); IsPaused.Value = false; } From 55c5ef898d2cba265b877bf1d4a5195a1b14c6bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 17:06:40 +0900 Subject: [PATCH 219/278] Remove delay on entering player --- osu.Game/Screens/Play/GameplayClockContainer.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 3654dc679c..2d1ba3f2ab 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -110,11 +110,8 @@ namespace osu.Game.Screens.Play adjustableClock.ChangeSource(sourceClock); updateRate(); - this.Delay(750).Schedule(() => - { - if (!IsPaused.Value) - Start(); - }); + if (!IsPaused.Value) + Start(); }); }); } From 6856571f17d06cd8080b19d967846347a54565af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 18:45:58 +0900 Subject: [PATCH 220/278] Fix incorrect seek target --- osu.Game/Screens/Play/GameplayClockContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 2d1ba3f2ab..6b12430552 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -120,7 +120,7 @@ namespace osu.Game.Screens.Play { // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time // This accounts for the audio clock source potentially taking time to enter a completely stopped state - adjustableClock.Seek(GameplayClock.CurrentTime); + Seek(GameplayClock.CurrentTime); adjustableClock.Start(); IsPaused.Value = false; } From 48e82d4b1c742dff5bbe101ebf6ffefcfa044809 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 18:47:28 +0900 Subject: [PATCH 221/278] Fix hold for menu button's icon being incorrect --- osu.Game/Screens/Play/HUD/HoldForMenuButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index 6883f246e4..c0ee5e6142 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -129,7 +129,7 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(15), - Icon = FontAwesome.Solid.TimesCircle + Icon = FontAwesome.Solid.Times }, } }; From 1f18c08cfc15a8184306ecce7915afff16c2061b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 Apr 2019 19:17:58 +0900 Subject: [PATCH 222/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a45cac2cb6..303587bf88 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 70edc01821..e45a76dbac 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 414d55548439b4a1e5e16f1da7830bd5aedc3296 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 22 Apr 2019 19:24:57 +0900 Subject: [PATCH 223/278] Fix possible exit from non-current screen --- 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 5e019a7b3a..1183396369 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -276,7 +276,7 @@ namespace osu.Game.Screens.Multi updatePollingRate(isIdle.Value); - if (screenStack.CurrentScreen == null) + if (screenStack.CurrentScreen == null && this.IsCurrentScreen()) this.Exit(); } From 52336e9062affa6742ad49c7802f31153364e04a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Apr 2019 11:52:42 +0900 Subject: [PATCH 224/278] Fix pause tests --- osu.Game/Tests/Visual/PlayerTestCase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index d308b86b5a..fca4fccae0 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual public void SetUpSteps() { AddStep(ruleset.RulesetInfo.Name, loadPlayer); - AddUntilStep(() => Player.IsLoaded, "player loaded"); + AddUntilStep(() => Player.IsLoaded && Player.Alpha == 1, "player loaded"); } protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); From 6add3952883f7d8b40f7e2cfd3ec0061cffa0f9b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 23 Apr 2019 13:32:44 +0900 Subject: [PATCH 225/278] Fix gameplay cursor being hidden in tests/replays --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 3 +++ osu.Game/Tests/Visual/ManualInputManagerTestCase.cs | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 2866e81682..302380744a 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -225,6 +225,9 @@ namespace osu.Game.Rulesets.UI if (replayInputManager.ReplayInputHandler != null) replayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; + + if (!ProvidingUserCursor) + Playfield.Cursor?.Show(); } /// diff --git a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs index f14ac833e4..9b1ccdd6a4 100644 --- a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs +++ b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs @@ -4,17 +4,24 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing.Input; +using osu.Game.Graphics.Cursor; namespace osu.Game.Tests.Visual { public abstract class ManualInputManagerTestCase : OsuTestCase { - protected override Container Content => InputManager; + protected override Container Content => content; + private readonly Container content; + protected readonly ManualInputManager InputManager; protected ManualInputManagerTestCase() { - base.Content.Add(InputManager = new ManualInputManager { UseParentInput = true }); + base.Content.Add(InputManager = new ManualInputManager + { + UseParentInput = true, + Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }, + }); } /// From 6c568d228fe7edb316492c4b4c32aae595c3b333 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 23 Apr 2019 13:45:51 +0900 Subject: [PATCH 226/278] Add comment --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 302380744a..01ae637158 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -227,7 +227,10 @@ namespace osu.Game.Rulesets.UI replayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; if (!ProvidingUserCursor) + { + // The cursor is hidden by default (see Playfield.load()), but should be shown when there's a replay Playfield.Cursor?.Show(); + } } /// From 0838206ddd3c54d2ec9f2d7cfc015da931a97a0c Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 22 Apr 2019 22:44:43 -0700 Subject: [PATCH 227/278] Shorten multiplayer header to multi --- osu.Game/Screens/Multi/Header.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 7924086389..b9354cac7d 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -79,7 +79,7 @@ namespace osu.Game.Screens.Multi [BackgroundDependencyLoader] private void load(OsuColour colours) { - Title = "multiplayer"; + Title = "multi"; Icon = OsuIcon.Multi; AccentColour = colours.Yellow; } From 80e1568e974f0cfa5efd0e8a4b1c2298c7fffefc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 13:44:21 +0900 Subject: [PATCH 228/278] Fix FrameStabilityContainer performing frame-stable seeks --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index c307520aca..2866ce08ed 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -68,6 +68,8 @@ namespace osu.Game.Rulesets.UI private const double sixty_frame_time = 1000.0 / 60; + private bool firstConsumption = true; + public override bool UpdateSubTree() { requireMoreUpdateLoops = true; @@ -103,7 +105,14 @@ namespace osu.Game.Rulesets.UI try { - if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) + if (firstConsumption) + { + // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. + // Instead we perform an initial seek to the proposed time. + manualClock.CurrentTime = newProposedTime; + firstConsumption = false; + } + else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) { newProposedTime = newProposedTime > manualClock.CurrentTime ? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time) From 60328cf1fb840344d3919ee80638ffe01b5010cc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 15:23:00 +0900 Subject: [PATCH 229/278] Ensure FrameStabilityContainer's ElapsedTime is zero on initial seek --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 2866ce08ed..ad15bcf057 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -110,6 +110,10 @@ namespace osu.Game.Rulesets.UI // On the first update, frame-stability seeking would result in unexpected/unwanted behaviour. // Instead we perform an initial seek to the proposed time. manualClock.CurrentTime = newProposedTime; + + // do a second process to clear out ElapsedTime + framedClock.ProcessFrame(); + firstConsumption = false; } else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) From a3e7ec0a14b85acec83e68963bb5d44e99a96300 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 15:23:31 +0900 Subject: [PATCH 230/278] Add tests for FrameStabilityContainer --- .../TestCaseFrameStabilityContainer.cs | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs new file mode 100644 index 0000000000..ca0607cd6b --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -0,0 +1,149 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Timing; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestCaseFrameStabilityContainer : OsuTestCase + { + private ManualClock manualClock; + + private Container mainContainer; + + private ClockConsumingChild consumer; + + [SetUp] + public void SetUp() + { + Child = mainContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Clock = new FramedClock(manualClock = new ManualClock()), + }; + } + + [Test] + public void TestLargeJumps() + { + createStabilityContainer(); + seekManualTo(100000); + + confirmSeek(100000); + checkFrameCount(6000); + + seekManualTo(0); + + confirmSeek(0); + checkFrameCount(12000); + } + + [Test] + public void TestSmallJumps() + { + createStabilityContainer(); + seekManualTo(40); + + confirmSeek(40); + checkFrameCount(3); + + seekManualTo(0); + + confirmSeek(0); + checkFrameCount(6); + } + + [Test] + public void TestSingleFrameJump() + { + createStabilityContainer(); + seekManualTo(8); + confirmSeek(8); + checkFrameCount(1); + + seekManualTo(16); + confirmSeek(16); + checkFrameCount(2); + } + + [Test] + public void TestInitialSeek() + { + seekManualTo(100000); + + createStabilityContainer(); + + confirmSeek(100000); + checkFrameCount(0); + } + + private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild())); + + private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time); + + private void confirmSeek(double time) => AddUntilStep($"wait for seek to {time}", () => consumer.Clock.CurrentTime == time); + + private void checkFrameCount(int frames) => + AddAssert($"elapsed frames is {frames}", () => consumer.ElapsedFrames == frames); + + public class ClockConsumingChild : CompositeDrawable + { + private readonly OsuSpriteText text; + private readonly OsuSpriteText text2; + private readonly OsuSpriteText text3; + + public ClockConsumingChild() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + InternalChildren = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + text2 = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + text3 = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + } + }, + }; + } + + public int ElapsedFrames; + + protected override void Update() + { + base.Update(); + + if (Clock.ElapsedFrameTime != 0) + ElapsedFrames++; + + text.Text = $"current time: {Clock.CurrentTime:F0}"; + if (Clock.ElapsedFrameTime != 0) + text2.Text = $"last elapsed frame time: {Clock.ElapsedFrameTime:F0}"; + text3.Text = $"total frames: {ElapsedFrames:F0}"; + } + } + } +} From e69963e60e2627f9682de1835ea1f3c2388b50c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 12:35:34 +0900 Subject: [PATCH 231/278] Ensure there is enough time before the first object in osu! (roughly following osu-stable specs) --- osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index ba7241c165..72adb4624d 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Input; @@ -61,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.UI get { var first = (OsuHitObject)Objects.First(); - return first.StartTime - first.TimePreempt; + return first.StartTime - Math.Max(2000, first.TimePreempt); } } } From efaedafc0870bdff673a37034b57a615a6e59d72 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 13:53:05 +0900 Subject: [PATCH 232/278] Fix (legacy) AudioLeadIn being used incorrectly. This lead-in is intended to specify a value before zero, not a value before the start time. Also removes an unnecessary ProcessFrame call (it happens within Seek itself). --- osu.Game/Screens/Play/GameplayClockContainer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 6b12430552..f1eed3f662 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -95,8 +95,7 @@ namespace osu.Game.Screens.Play UserPlaybackRate.ValueChanged += _ => updateRate(); - Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn)); - adjustableClock.ProcessFrame(); + Seek(Math.Min(-beatmap.BeatmapInfo.AudioLeadIn, gameplayStartTime)); } public void Restart() From bb69330e9f85e1e76140e225e497a2cd45a1311f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 14:01:46 +0900 Subject: [PATCH 233/278] Call ProcessFrame on the userOffsetClock after a seek Without doing this, GameplayClock can be left in an incorrect state after a seek (due to the userOffsetClock being its own FramedClock). --- osu.Game/Screens/Play/GameplayClockContainer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index f1eed3f662..c151e598f7 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -136,6 +136,9 @@ namespace osu.Game.Screens.Play // remove the offset component here because most of the time we want the seek to be aligned to gameplay, not the audio track. // we may want to consider reversing the application of offsets in the future as it may feel more correct. adjustableClock.Seek(time - totalOffset); + + // manually process frame to ensure GameplayClock is correctly updated after a seek. + userOffsetClock.ProcessFrame(); } public void Stop() From 3b36a4982deabef006ccd97909c3f2730abbe51e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 15:46:21 +0900 Subject: [PATCH 234/278] Fix tests running under nUnit and running multiple times in concession --- .../Gameplay/TestCaseFrameStabilityContainer.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index ca0607cd6b..bc30648566 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.UI; @@ -12,14 +13,13 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestCaseFrameStabilityContainer : OsuTestCase { - private ManualClock manualClock; + private readonly ManualClock manualClock; - private Container mainContainer; + private readonly Container mainContainer; private ClockConsumingChild consumer; - [SetUp] - public void SetUp() + public TestCaseFrameStabilityContainer() { Child = mainContainer = new Container { @@ -31,6 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestLargeJumps() { + seekManualTo(0); createStabilityContainer(); seekManualTo(100000); @@ -46,6 +47,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestSmallJumps() { + seekManualTo(0); createStabilityContainer(); seekManualTo(40); @@ -61,6 +63,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestSingleFrameJump() { + seekManualTo(0); createStabilityContainer(); seekManualTo(8); confirmSeek(8); @@ -75,7 +78,6 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestInitialSeek() { seekManualTo(100000); - createStabilityContainer(); confirmSeek(100000); From f273f5daae7e6224ead6491e491b391fc261db07 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Apr 2019 15:55:51 +0900 Subject: [PATCH 235/278] Remove unnecessary using statement --- .../Visual/Gameplay/TestCaseFrameStabilityContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index bc30648566..5cd01fe9a8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -4,7 +4,6 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.UI; From 8222923ab8838cf754874df7edbe62fa37679291 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 24 Apr 2019 16:20:51 +0900 Subject: [PATCH 236/278] Only track logo if we're still the current screen --- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6a55fe278b..4403cae883 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -163,7 +163,11 @@ namespace osu.Game.Screens.Play logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); logo.FadeIn(350); - Scheduler.AddDelayed(() => { content.StartTracking(logo, resuming ? 0 : 500, Easing.InOutExpo); }, resuming ? 0 : 500); + Scheduler.AddDelayed(() => + { + if (this.IsCurrentScreen()) + content.StartTracking(logo, resuming ? 0 : 500, Easing.InOutExpo); + }, resuming ? 0 : 500); } protected override void LogoExiting(OsuLogo logo) From 8dc7fd8223235fa56c335840b79354c1e1d46be6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Apr 2019 12:16:12 +0900 Subject: [PATCH 237/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 303587bf88..22afce9c86 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e45a76dbac..eaebcc3361 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 6fdcd98caadb0415e4bddd198a1e5e5804a56ea7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Apr 2019 14:15:07 +0900 Subject: [PATCH 238/278] Don't play screen "back" sample when retrying --- osu.Game/Screens/OsuScreen.cs | 5 ++++- osu.Game/Screens/Play/PlayerLoader.cs | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c1a822c75c..9d53e43b80 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -59,6 +59,8 @@ namespace osu.Game.Screens private SampleChannel sampleExit; + protected virtual bool PlayResumeSound => true; + public virtual float BackgroundParallaxAmount => 1; public Bindable Beatmap { get; private set; } @@ -117,7 +119,8 @@ namespace osu.Game.Screens public override void OnResuming(IScreen last) { - sampleExit?.Play(); + if (PlayResumeSound) + sampleExit?.Play(); applyArrivingDefaults(true); base.OnResuming(last); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6a55fe278b..d49ac0ed16 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -44,6 +44,8 @@ namespace osu.Game.Screens.Play public override bool DisallowExternalBeatmapRulesetChanges => true; + protected override bool PlayResumeSound => false; + private Task loadTask; private InputManager inputManager; From 0bd35ab7bbdb29705813c02474c16d2db35dd36f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 17:36:17 +0900 Subject: [PATCH 239/278] Turn on warnings, resolve issues --- .../Visual/Gameplay/TestCaseSkinReloadable.cs | 12 ++-------- osu.Game/Audio/IPreviewTrackOwner.cs | 2 +- osu.Game/Beatmaps/BeatmapConverter.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 3 +-- osu.Game/Beatmaps/BindableBeatmap.cs | 4 ++-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 12 +++++++++- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 + osu.Game/Database/ArchiveModelManager.cs | 2 +- osu.Game/Database/DatabaseContextFactory.cs | 3 +-- osu.Game/Database/OsuDbContext.cs | 2 +- .../Graphics/Containers/LinkFlowContainer.cs | 2 +- .../Containers/LogoTrackingContainer.cs | 3 +-- osu.Game/Graphics/OsuFont.cs | 5 ++-- .../UserInterface/ScreenBreadcrumbControl.cs | 2 +- osu.Game/Online/API/APIAccess.cs | 2 +- .../Requests/Responses/APILegacyScoreInfo.cs | 2 -- .../Responses/APIUserMostPlayedBeatmap.cs | 8 +++---- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 2 -- osu.Game/OsuGame.cs | 1 - .../Chat/Tabs/ChannelSelectorTabItem.cs | 2 +- .../Chat/Tabs/PrivateChannelTabItem.cs | 4 ---- osu.Game/Overlays/HoldToConfirmOverlay.cs | 2 +- osu.Game/Overlays/MusicController.cs | 1 - .../Settings/RulesetSettingsSubsection.cs | 3 ++- .../Overlays/Settings/SettingsEnumDropdown.cs | 2 +- .../Difficulty/DifficultyCalculator.cs | 2 +- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 4 +++- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 6 ++++- .../Mods/IApplicableToBeatmapConverter.cs | 2 -- .../Rulesets/Mods/IApplicableToHitObject.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 5 ++-- osu.Game/Rulesets/Objects/HitObject.cs | 4 +--- osu.Game/Rulesets/Objects/HitWindows.cs | 2 +- osu.Game/Rulesets/Objects/SliderPath.cs | 7 ------ osu.Game/Rulesets/Ruleset.cs | 1 + osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 3 --- osu.Game/Rulesets/UI/DrawableRuleset.cs | 4 +++- .../Rulesets/UI/GameplayCursorContainer.cs | 2 +- osu.Game/Rulesets/UI/Playfield.cs | 1 - .../Scrolling/Algorithms/IScrollAlgorithm.cs | 2 +- .../UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- osu.Game/Screens/BackgroundScreenStack.cs | 2 +- .../Compose/Components/SelectionHandler.cs | 3 +-- .../Timeline/ZoomableScrollContainer.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 3 --- .../LabelledComponents/LabelledTextBox.cs | 7 ------ .../Multi/Components/DisableableTabControl.cs | 6 ++--- .../Lounge/Components/ParticipantInfo.cs | 24 ------------------- .../Multi/Lounge/Components/RoomInspector.cs | 2 +- .../Multi/Match/Components/GameTypePicker.cs | 2 +- .../Screens/Multi/Match/Components/Info.cs | 3 +-- .../Match/Components/MatchSettingsOverlay.cs | 4 ++-- .../Components/RoomAvailabilityPicker.cs | 2 +- .../Screens/Multi/MultiplayerComposite.cs | 4 ++-- .../Screens/Multi/MultiplayerSubScreen.cs | 22 +---------------- osu.Game/Screens/Multi/RoomManager.cs | 2 +- osu.Game/Screens/Play/GameplayClock.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 1 - .../Screens/Select/Carousel/CarouselItem.cs | 2 -- osu.Game/Screens/Select/SongSelect.cs | 2 -- osu.Game/Skinning/ISkin.cs | 24 +++++++++++++++++++ osu.Game/Skinning/ISkinSource.cs | 13 +--------- .../Skinning/LocalSkinOverrideContainer.cs | 14 +++++------ osu.Game/Skinning/Skin.cs | 4 +--- osu.Game/Tests/Visual/AllPlayersTestCase.cs | 4 ++-- osu.Game/Tests/Visual/EditorClockTestCase.cs | 2 +- osu.Game/Tests/Visual/OsuTestCase.cs | 2 +- osu.Game/Tests/Visual/PlayerTestCase.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 71 files changed, 116 insertions(+), 182 deletions(-) create mode 100644 osu.Game/Skinning/ISkin.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseSkinReloadable.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseSkinReloadable.cs index a9fbf35d37..56ab70b400 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseSkinReloadable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseSkinReloadable.cs @@ -120,12 +120,8 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class SecondarySource : ISkinSource + private class SecondarySource : ISkin { - public event Action SourceChanged; - - public void TriggerSourceChanged() => SourceChanged?.Invoke(); - public Drawable GetDrawableComponent(string componentName) => new SecondarySourceBox(); public Texture GetTexture(string componentName) => throw new NotImplementedException(); @@ -135,12 +131,8 @@ namespace osu.Game.Tests.Visual.Gameplay public TValue GetValue(Func query) where TConfiguration : SkinConfiguration => throw new NotImplementedException(); } - private class SkinSourceContainer : Container, ISkinSource + private class SkinSourceContainer : Container, ISkin { - public event Action SourceChanged; - - public void TriggerSourceChanged() => SourceChanged?.Invoke(); - public Drawable GetDrawableComponent(string componentName) => new BaseSourceBox(); public Texture GetTexture(string componentName) => throw new NotImplementedException(); diff --git a/osu.Game/Audio/IPreviewTrackOwner.cs b/osu.Game/Audio/IPreviewTrackOwner.cs index fdcae65e3c..8ab93257a5 100644 --- a/osu.Game/Audio/IPreviewTrackOwner.cs +++ b/osu.Game/Audio/IPreviewTrackOwner.cs @@ -4,7 +4,7 @@ namespace osu.Game.Audio { /// - /// Interface for objects that can own s. + /// Interface for objects that can own s. /// /// /// s can cancel the currently playing through the diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index b6fa6674f6..7922843626 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -98,7 +98,7 @@ namespace osu.Game.Beatmaps protected abstract IEnumerable ValidConversionTypes { get; } /// - /// Creates the that will be returned by this . + /// Creates the that will be returned by this . /// protected virtual Beatmap CreateBeatmap() => new Beatmap(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 9caa64ec96..a36a8ea7dd 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -217,7 +217,7 @@ namespace osu.Game.Beatmaps { request.Perform(api); } - catch (Exception e) + catch { // no need to handle here as exceptions will filter down to request.Failure above. } @@ -382,7 +382,6 @@ namespace osu.Game.Beatmaps /// Query the API to populate missing values like OnlineBeatmapID / OnlineBeatmapSetID or (Rank-)Status. /// /// The beatmap to populate. - /// The other beatmaps contained within this set. /// Whether to re-query if the provided beatmap already has populated values. /// True if population was successful. private bool fetchAndPopulateOnlineValues(BeatmapInfo beatmap, bool force = false) diff --git a/osu.Game/Beatmaps/BindableBeatmap.cs b/osu.Game/Beatmaps/BindableBeatmap.cs index 657dc06297..27bad65062 100644 --- a/osu.Game/Beatmaps/BindableBeatmap.cs +++ b/osu.Game/Beatmaps/BindableBeatmap.cs @@ -12,7 +12,7 @@ namespace osu.Game.Beatmaps { /// /// A for the beatmap. - /// This should be used sparingly in-favour of . + /// This should be used sparingly in-favour of . /// public abstract class BindableBeatmap : NonNullableBindable { @@ -67,6 +67,6 @@ namespace osu.Game.Beatmaps /// If you are further binding to events of the retrieved , ensure a local reference is held. /// [NotNull] - public abstract BindableBeatmap GetBoundCopy(); + public new abstract BindableBeatmap GetBoundCopy(); } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 58463d2219..7d25ca3ede 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Difficulty; @@ -73,9 +74,18 @@ namespace osu.Game.Beatmaps private class DummyBeatmapConverter : IBeatmapConverter { public event Action> ObjectConverted; + public IBeatmap Beatmap { get; set; } + public bool CanConvert => true; - public IBeatmap Convert() => Beatmap; + + public IBeatmap Convert() + { + foreach (var obj in Beatmap.HitObjects) + ObjectConverted?.Invoke(obj, obj.Yield()); + + return Beatmap; + } } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 040f582e3b..31cfe076cd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -95,7 +95,7 @@ namespace osu.Game.Beatmaps.Formats { colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), split.Length == 4 ? byte.Parse(split[3]) : (byte)255); } - catch (Exception e) + catch { throw new InvalidOperationException(@"Color must be specified with 8-bit integer components"); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 8989785dcd..4b0720d867 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -73,6 +73,7 @@ namespace osu.Game.Beatmaps /// /// /// The to create a playable for. + /// The s to apply to the . /// The converted . /// If could not be converted to . public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 3805921ac2..41f8c64853 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -563,7 +563,7 @@ namespace osu.Game.Database /// /// Check whether an existing model already exists for a new import item. /// - /// The new model proposed for import. + /// The new model proposed for import. /// An existing model which matches the criteria to skip importing, else null. protected TModel CheckForExisting(TModel model) => model.Hash == null ? null : ModelStore.ConsumableItems.FirstOrDefault(b => b.Hash == model.Hash); diff --git a/osu.Game/Database/DatabaseContextFactory.cs b/osu.Game/Database/DatabaseContextFactory.cs index f6250732d9..554337c477 100644 --- a/osu.Game/Database/DatabaseContextFactory.cs +++ b/osu.Game/Database/DatabaseContextFactory.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; using System.Threading; using Microsoft.EntityFrameworkCore.Storage; @@ -67,7 +66,7 @@ namespace osu.Game.Database context = threadContexts.Value; } } - catch (Exception e) + catch { // retrieval of a context could trigger a fatal error. Monitor.Exit(writeLock); diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index 17efe2c839..f4cd23f5a5 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -70,7 +70,7 @@ namespace osu.Game.Database cmd.ExecuteNonQuery(); } } - catch (Exception e) + catch { connection.Close(); throw; diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index eefbeea24c..222336d663 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -103,7 +103,7 @@ namespace osu.Game.Graphics.Containers { channelManager?.OpenChannel(linkArgument); } - catch (ChannelNotFoundException e) + catch (ChannelNotFoundException) { Logger.Log($"The requested channel \"{linkArgument}\" does not exist"); } diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index fb23038dde..23015e8bf5 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -30,7 +30,6 @@ namespace osu.Game.Graphics.Containers /// Assign the logo that should track the facade's position, as well as how it should transform to its initial position. /// /// The instance of the logo to be used for tracking. - /// The scale of the facade. Does not actually affect the logo itself. /// The duration of the initial transform. Default is instant. /// The easing type of the initial transform. public void StartTracking(OsuLogo logo, double duration = 0, Easing easing = Easing.None) @@ -132,7 +131,7 @@ namespace osu.Game.Graphics.Containers private class InternalFacade : Facade { - public void SetSize(Vector2 size) + public new void SetSize(Vector2 size) { base.SetSize(size); } diff --git a/osu.Game/Graphics/OsuFont.cs b/osu.Game/Graphics/OsuFont.cs index c8a736f49a..5324b269ee 100644 --- a/osu.Game/Graphics/OsuFont.cs +++ b/osu.Game/Graphics/OsuFont.cs @@ -61,9 +61,9 @@ namespace osu.Game.Graphics /// /// Retrieves the string representation of a . /// - /// The . + /// The family string. /// The . - /// The string representation of in the specified . + /// The string representation of in the specified . public static string GetWeightString(string family, FontWeight weight) { string weightString = weight.ToString(); @@ -81,6 +81,7 @@ namespace osu.Game.Graphics /// /// Creates a new by applying adjustments to this . /// + /// The base . /// The font typeface. If null, the value is copied from this . /// The text size. If null, the value is copied from this . /// The font weight. If null, the value is copied from this . diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index f564a4b5a8..3e0a6c3265 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -8,7 +8,7 @@ using osu.Framework.Screens; namespace osu.Game.Graphics.UserInterface { /// - /// A which follows the active screen (and allows navigation) in a stack. + /// A which follows the active screen (and allows navigation) in a stack. /// public class ScreenBreadcrumbControl : BreadcrumbControl { diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index c5f6ef41c2..d5a496dc17 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -253,7 +253,7 @@ namespace osu.Game.Online.API handleWebException(we); return false; } - catch (Exception e) + catch { return false; } diff --git a/osu.Game/Online/API/Requests/Responses/APILegacyScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/APILegacyScoreInfo.cs index 8ee71ce9ac..ca3a77a140 100644 --- a/osu.Game/Online/API/Requests/Responses/APILegacyScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/APILegacyScoreInfo.cs @@ -7,7 +7,6 @@ using System.Linq; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Rulesets.Scoring; using osu.Game.Scoring.Legacy; using osu.Game.Users; @@ -71,7 +70,6 @@ namespace osu.Game.Online.API.Requests.Responses { foreach (var kvp in value) { - HitResult newKey; switch (kvp.Key) { case @"count_geki": diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs index 8177f99abe..4614fe29b7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -10,16 +10,16 @@ namespace osu.Game.Online.API.Requests.Responses public class APIUserMostPlayedBeatmap { [JsonProperty("beatmap_id")] - public int BeatmapID; + public int BeatmapID { get; set; } [JsonProperty("count")] - public int PlayCount; + public int PlayCount { get; set; } [JsonProperty] - private BeatmapInfo beatmap; + private BeatmapInfo beatmap { get; set; } [JsonProperty] - private APIBeatmapSet beatmapSet; + private APIBeatmapSet beatmapSet { get; set; } public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) { diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 438bf231c4..ae4a056033 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -27,8 +27,6 @@ namespace osu.Game.Online.Chat protected ChannelManager ChannelManager; - private ScrollContainer scroll; - private DrawableChannel drawableChannel; private readonly bool postingTextbox; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 30f98aa1ce..4ce056195c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -272,7 +272,6 @@ namespace osu.Game /// Present a score's replay immediately. /// The user should have already requested this interactively. /// - /// The beatmap to select. public void PresentScore(ScoreInfo score) { var databasedScore = ScoreManager.GetScore(score); diff --git a/osu.Game/Overlays/Chat/Tabs/ChannelSelectorTabItem.cs b/osu.Game/Overlays/Chat/Tabs/ChannelSelectorTabItem.cs index 52260506fe..c26ecfd86f 100644 --- a/osu.Game/Overlays/Chat/Tabs/ChannelSelectorTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/ChannelSelectorTabItem.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Chat.Tabs } [BackgroundDependencyLoader] - private new void load(OsuColour colour) + private void load(OsuColour colour) { BackgroundInactive = colour.Gray2; BackgroundActive = colour.Gray3; diff --git a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs index 8aa6d6fecd..b8165e70cb 100644 --- a/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs +++ b/osu.Game/Overlays/Chat/Tabs/PrivateChannelTabItem.cs @@ -9,7 +9,6 @@ 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.Online.Chat; using osu.Game.Users; using osuTK; @@ -18,9 +17,6 @@ namespace osu.Game.Overlays.Chat.Tabs { public class PrivateChannelTabItem : ChannelTabItem { - private readonly OsuSpriteText username; - private readonly Avatar avatarContainer; - protected override IconUsage DisplayIcon => FontAwesome.Solid.At; public PrivateChannelTabItem(Channel value) diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index 154aff605a..fb38ddcbd1 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays { /// /// An overlay which will display a black screen that dims over a period before confirming an exit action. - /// Action is BYO (derived class will need to call and from a user event). + /// Action is BYO (derived class will need to call and from a user event). /// public abstract class HoldToConfirmOverlay : HoldToConfirmContainer { diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c250d3b62a..9046a196da 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -50,7 +50,6 @@ namespace osu.Game.Overlays private BeatmapManager beatmaps; private List beatmapSets; - private BeatmapSetInfo currentSet; private Container dragContainer; private Container playerContainer; diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index a16e852902..93b07fbac7 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Configuration; @@ -9,7 +10,7 @@ namespace osu.Game.Overlays.Settings { /// /// A which provides subclasses with the - /// from the 's . + /// from the 's . /// public abstract class RulesetSettingsSubsection : SettingsSubsection { diff --git a/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs b/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs index 11cdbf6e0a..9f09f251c2 100644 --- a/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs +++ b/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings { protected override OsuDropdown CreateDropdown() => new DropdownControl(); - protected class DropdownControl : OsuEnumDropdown + protected new class DropdownControl : OsuEnumDropdown { public DropdownControl() { diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 14f7665e05..5eabe1e936 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Difficulty /// /// Creates the s to calculate the difficulty of an . /// - /// The whose difficulty will be calculated.The whose difficulty will be calculated. /// The s. protected abstract Skill[] CreateSkills(IBeatmap beatmap); } diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 74aa9ace2d..f12591cef4 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit.Compose; using osuTK; @@ -108,7 +109,8 @@ namespace osu.Game.Rulesets.Edit } /// - /// Invokes , refreshing and parameters for the . + /// Invokes , + /// refreshing and parameters for the . /// protected void ApplyDefaultsToHitObject() => HitObject.ApplyDefaults(beatmap.Value.Beatmap.ControlPointInfo, beatmap.Value.Beatmap.BeatmapInfo.BaseDifficulty); diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 85b6c91a07..01992cbbd3 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -68,9 +68,11 @@ namespace osu.Game.Rulesets.Edit get => state; set { - if (state == value) return; + if (state == value) + return; state = value; + switch (state) { case SelectionState.Selected: @@ -82,6 +84,8 @@ namespace osu.Game.Rulesets.Edit Deselected?.Invoke(this); break; } + + StateChanged?.Invoke(state); } } diff --git a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs index eb80fa131a..8cefb02904 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs @@ -2,14 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Beatmaps; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mods { /// /// Interface for a that applies changes to a . /// - /// The type of converted . public interface IApplicableToBeatmapConverter : IApplicableMod { /// diff --git a/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs b/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs index c13b62812b..f7f81c92c0 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mods public interface IApplicableToHitObject : IApplicableMod { /// - /// Applies this to a . + /// Applies this to a . /// /// The to apply to. void ApplyToHitObject(HitObject hitObject); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index a7cfbd3300..2e983b8fe1 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; using osu.Game.Audio; using osu.Game.Graphics; @@ -58,7 +59,7 @@ namespace osu.Game.Rulesets.Objects.Drawables public bool AllJudged => Judged && NestedHitObjects.All(h => h.AllJudged); /// - /// Whether this has been hit. This occurs if is . + /// Whether this has been hit. This occurs if is hit. /// Note: This does NOT include nested hitobjects. /// public bool IsHit => Result?.IsHit ?? false; @@ -223,7 +224,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } /// - /// Will called at least once after the of this has been passed. + /// Will called at least once after the of this has been passed. /// internal void OnLifetimeEnd() { diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index fd542be67d..cede2e50d0 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -53,8 +53,6 @@ namespace osu.Game.Rulesets.Objects [JsonIgnore] public bool Kiai { get; private set; } - private float overallDifficulty = BeatmapDifficulty.DEFAULT_DIFFICULTY; - /// /// The hit windows for this . /// @@ -115,7 +113,7 @@ namespace osu.Game.Rulesets.Objects /// Creates the for this . /// This can be null to indicate that the has no . /// - /// This will only be invoked if hasn't been set externally (e.g. from a . + /// This will only be invoked if hasn't been set externally (e.g. from a . /// /// protected virtual HitWindows CreateHitWindows() => new HitWindows(); diff --git a/osu.Game/Rulesets/Objects/HitWindows.cs b/osu.Game/Rulesets/Objects/HitWindows.cs index c5b7686da6..589c72957b 100644 --- a/osu.Game/Rulesets/Objects/HitWindows.cs +++ b/osu.Game/Rulesets/Objects/HitWindows.cs @@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Objects /// /// Given a time offset, whether the can ever be hit in the future with a non- result. - /// This happens if is less than what is required for a result. + /// This happens if is less than what is required for . /// /// The time offset. /// Whether the can be hit at any point in the future from this time offset. diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index 1e9767a54f..e312b004ba 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -277,12 +277,5 @@ namespace osu.Game.Rulesets.Objects return ControlPoints.SequenceEqual(other.ControlPoints) && ExpectedDistance.Equals(other.ExpectedDistance) && Type == other.Type; } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - - return obj is SliderPath other && Equals(other); - } } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3521c17b23..42b1322cae 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -53,6 +53,7 @@ namespace osu.Game.Rulesets /// Attempt to create a hit renderer for a beatmap /// /// The beatmap to create the hit renderer for. + /// The s to apply. /// Unable to successfully load the beatmap to be usable with this ruleset. /// public abstract DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods); diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ba71e1e9b2..a2937ff959 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -154,7 +154,6 @@ namespace osu.Game.Rulesets.Scoring /// /// Notifies subscribers of that a new judgement has occurred. /// - /// The judgement to notify subscribers of. /// The judgement scoring result to notify subscribers of. protected void NotifyNewJudgement(JudgementResult result) { @@ -283,7 +282,6 @@ namespace osu.Game.Rulesets.Scoring /// /// Reverts the score change of a that was applied to this . /// - /// The judgement to remove. /// The judgement scoring result. private void revertResult(JudgementResult result) { @@ -340,7 +338,6 @@ namespace osu.Game.Rulesets.Scoring /// /// Reverts the score change of a that was applied to this . /// - /// The judgement to remove. /// The judgement scoring result. protected virtual void RevertResult(JudgementResult result) { diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 01ae637158..df9effb321 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -93,6 +93,7 @@ namespace osu.Game.Rulesets.UI /// /// The ruleset being represented. /// The beatmap to create the hit renderer for. + /// The s to apply. protected DrawableRuleset(Ruleset ruleset, WorkingBeatmap workingBeatmap, IReadOnlyList mods) : base(ruleset) { @@ -275,7 +276,8 @@ namespace osu.Game.Rulesets.UI /// /// Applies the active mods to this DrawableRuleset. /// - /// + /// The s to apply. + /// The to apply. private void applyRulesetMods(IReadOnlyList mods, OsuConfigManager config) { if (mods == null) diff --git a/osu.Game/Rulesets/UI/GameplayCursorContainer.cs b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs index de73c08809..41edfa0b68 100644 --- a/osu.Game/Rulesets/UI/GameplayCursorContainer.cs +++ b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.UI public class GameplayCursorContainer : CursorContainer { /// - /// Because Show/Hide are executed by a parent, is updated immediately even if the cursor + /// Because Show/Hide are executed by a parent, is updated immediately even if the cursor /// is in a non-updating state (via limitations). /// /// This holds the true visibility value. diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index a99c16a610..a073ad246b 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -100,7 +100,6 @@ namespace osu.Game.Rulesets.UI /// /// Provide an optional cursor which is to be used for gameplay. - /// If providing a cursor, must also point to a valid target container. /// /// The cursor, or null if a cursor is not rqeuired. protected virtual GameplayCursorContainer CreateCursor() => null; diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs index a104b0629f..b7a5eedc22 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms /// The current time. /// The amount of visible time. /// The absolute spatial length through . - /// The time at which == . + /// The time at which == . double TimeAt(float position, double currentTime, double timeRange, float scrollLength); /// diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index dbe8d8c299..f21d0b4a66 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.UI.Scrolling protected virtual ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Sequential; /// - /// Whether the player can change . + /// Whether the player can change . /// protected virtual bool UserScrollSpeedAdjustment => true; diff --git a/osu.Game/Screens/BackgroundScreenStack.cs b/osu.Game/Screens/BackgroundScreenStack.cs index 5f82329496..9c0c5da0fb 100644 --- a/osu.Game/Screens/BackgroundScreenStack.cs +++ b/osu.Game/Screens/BackgroundScreenStack.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens //public float ParallaxAmount { set => parallax.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * value; } - public new void Push(BackgroundScreen screen) + public void Push(BackgroundScreen screen) { if (screen == null) return; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index bcb2bee601..11e649168f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -121,6 +121,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Handle a blueprint requesting selection. /// /// The blueprint. + /// The input state at the point of selection. internal void HandleSelectionRequested(SelectionBlueprint blueprint, InputState state) { if (state.Keyboard.ControlPressed) @@ -166,8 +167,6 @@ namespace osu.Game.Screens.Edit.Compose.Components var topLeft = new Vector2(float.MaxValue, float.MaxValue); var bottomRight = new Vector2(float.MinValue, float.MinValue); - bool hasSelection = false; - foreach (var blueprint in selectedBlueprints) { topLeft = Vector2.ComponentMin(topLeft, ToLocalSpace(blueprint.SelectionQuad.TopLeft)); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index f41b3cddc0..9b00a3998d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private readonly float scrollOffset; /// - /// Transforms to a new value. + /// Transforms to a new value. /// /// The focus point in absolute coordinates local to the content. /// The size of the content. diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 0ba1e74aca..09977454f0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -65,9 +65,6 @@ namespace osu.Game.Screens.Edit dependencies.Cache(beatDivisor); EditorMenuBar menuBar; - TimeInfoContainer timeInfo; - SummaryTimeline timeline; - PlaybackControl playback; var fileMenuItems = new List(); if (RuntimeInfo.IsDesktop) diff --git a/osu.Game/Screens/Edit/Setup/Components/LabelledComponents/LabelledTextBox.cs b/osu.Game/Screens/Edit/Setup/Components/LabelledComponents/LabelledTextBox.cs index 50d524d1f5..1c53fc7088 100644 --- a/osu.Game/Screens/Edit/Setup/Components/LabelledComponents/LabelledTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/Components/LabelledComponents/LabelledTextBox.cs @@ -60,14 +60,7 @@ namespace osu.Game.Screens.Edit.Setup.Components.LabelledComponents set => label.Colour = value; } - public Color4 BackgroundColour - { - get => content.Colour; - set => content.Colour = value; - } - private readonly OsuTextBox textBox; - private readonly Container content; private readonly OsuSpriteText label; public LabelledTextBox() diff --git a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs index b6b0332cf3..27b5aec4d3 100644 --- a/osu.Game/Screens/Multi/Components/DisableableTabControl.cs +++ b/osu.Game/Screens/Multi/Components/DisableableTabControl.cs @@ -13,15 +13,13 @@ namespace osu.Game.Screens.Multi.Components protected override void AddTabItem(TabItem tab, bool addToDropdown = true) { - if (tab is DisableableTabItem disableable) + if (tab is DisableableTabItem disableable) disableable.Enabled.BindTo(Enabled); base.AddTabItem(tab, addToDropdown); } - protected abstract class DisableableTabItem : TabItem + protected abstract class DisableableTabItem : TabItem { - public readonly BindableBool Enabled = new BindableBool(); - protected DisableableTabItem(T value) : base(value) { diff --git a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs index 51d3c93624..6570051040 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs @@ -25,8 +25,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components private void load(OsuColour colours) { OsuSpriteText summary; - OsuSpriteText levelRangeHigher; - OsuSpriteText levelRangeLower; Container flagContainer; LinkFlowContainer hostText; @@ -45,21 +43,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components Width = 22f, RelativeSizeAxes = Axes.Y, }, - /*new Container //todo: team banners - { - Width = 38f, - RelativeSizeAxes = Axes.Y, - CornerRadius = 2f, - Masking = true, - Children = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"ad387e"), - }, - }, - },*/ hostText = new LinkFlowContainer { Anchor = Anchor.CentreLeft, @@ -101,13 +84,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, true); ParticipantCount.BindValueChanged(count => summary.Text = "participant".ToQuantity(count.NewValue), true); - - /*Participants.BindValueChanged(e => - { - var ranks = v.Select(u => u.Statistics.Ranks.Global); - levelRangeLower.Text = ranks.Min().ToString(); - levelRangeHigher.Text = ranks.Max().ToString(); - });*/ } } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 5798fce457..1297090a32 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 30), - Current = Name + Current = RoomName }, }, }, diff --git a/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs index ccb957734f..b69cb9705d 100644 --- a/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/GameTypePicker.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Multi.Match.Components AddItem(new GameTypeTimeshift()); } - private class GameTypePickerItem : DisableableTabItem + private class GameTypePickerItem : DisableableTabItem { private const float transition_duration = 200; diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index a944d965bd..a185c4db50 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -30,7 +30,6 @@ namespace osu.Game.Screens.Multi.Match.Components ReadyButton readyButton; ViewBeatmapButton viewBeatmapButton; HostInfo hostInfo; - RoomStatusInfo statusInfo; InternalChildren = new Drawable[] { @@ -63,7 +62,7 @@ namespace osu.Game.Screens.Multi.Match.Components new OsuSpriteText { Font = OsuFont.GetFont(size: 30), - Current = Name + Current = RoomName }, new RoomStatusInfo(), } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 586a986111..359b5824c0 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -265,7 +265,7 @@ namespace osu.Game.Screens.Multi.Match.Components }; TypePicker.Current.BindValueChanged(type => typeLabel.Text = type.NewValue?.Name ?? string.Empty, true); - Name.BindValueChanged(name => NameField.Text = name.NewValue, true); + RoomName.BindValueChanged(name => NameField.Text = name.NewValue, true); Availability.BindValueChanged(availability => AvailabilityPicker.Current.Value = availability.NewValue, true); Type.BindValueChanged(type => TypePicker.Current.Value = type.NewValue, true); MaxParticipants.BindValueChanged(count => MaxParticipantsField.Text = count.NewValue?.ToString(), true); @@ -285,7 +285,7 @@ namespace osu.Game.Screens.Multi.Match.Components { hideError(); - Name.Value = NameField.Text; + RoomName.Value = NameField.Text; Availability.Value = AvailabilityPicker.Current.Value; Type.Value = TypePicker.Current.Value; diff --git a/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs index 8751e27552..9de4a61cde 100644 --- a/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/Multi/Match/Components/RoomAvailabilityPicker.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Multi.Match.Components AddItem(RoomAvailability.InviteOnly); } - private class RoomAvailabilityPickerItem : DisableableTabItem + private class RoomAvailabilityPickerItem : DisableableTabItem { private const float transition_duration = 200; diff --git a/osu.Game/Screens/Multi/MultiplayerComposite.cs b/osu.Game/Screens/Multi/MultiplayerComposite.cs index da6bba7865..8c09d576ff 100644 --- a/osu.Game/Screens/Multi/MultiplayerComposite.cs +++ b/osu.Game/Screens/Multi/MultiplayerComposite.cs @@ -16,8 +16,8 @@ namespace osu.Game.Screens.Multi [Resolved(typeof(Room))] protected Bindable RoomID { get; private set; } - [Resolved(typeof(Room))] - protected Bindable Name { get; private set; } + [Resolved(typeof(Room), nameof(Room.Name))] + protected Bindable RoomName { get; private set; } [Resolved(typeof(Room))] protected Bindable Host { get; private set; } diff --git a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs index 65e501b114..ff94f63f01 100644 --- a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs @@ -3,22 +3,17 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Graphics.Containers; -using osu.Game.Input.Bindings; namespace osu.Game.Screens.Multi { - public abstract class MultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen, IKeyBindingHandler + public abstract class MultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen { public override bool DisallowExternalBeatmapRulesetChanges => false; public virtual string ShortTitle => Title; - [Resolved(CanBeNull = true)] - protected OsuGame Game { get; private set; } - [Resolved(CanBeNull = true)] protected IRoomManager RoomManager { get; private set; } @@ -56,21 +51,6 @@ namespace osu.Game.Screens.Multi this.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); } - public override bool OnPressed(GlobalAction action) - { - if (!this.IsCurrentScreen()) return false; - - if (action == GlobalAction.Back) - { - this.Exit(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back; - public override string ToString() => Title; } } diff --git a/osu.Game/Screens/Multi/RoomManager.cs b/osu.Game/Screens/Multi/RoomManager.cs index 385cbe20e5..6f473aaafa 100644 --- a/osu.Game/Screens/Multi/RoomManager.cs +++ b/osu.Game/Screens/Multi/RoomManager.cs @@ -171,7 +171,7 @@ namespace osu.Game.Screens.Multi /// /// Adds a to the list of available rooms. /// - /// The to add.< + /// The to add. private void addRoom(Room room) { var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); diff --git a/osu.Game/Screens/Play/GameplayClock.cs b/osu.Game/Screens/Play/GameplayClock.cs index 3efcfa0f65..b1948d02d5 100644 --- a/osu.Game/Screens/Play/GameplayClock.cs +++ b/osu.Game/Screens/Play/GameplayClock.cs @@ -8,7 +8,7 @@ namespace osu.Game.Screens.Play { /// /// A clock which is used for gameplay elements that need to follow audio time 1:1. - /// Exposed via DI by . + /// Exposed via DI by . /// /// The main purpose of this clock is to stop components using it from accidentally processing the main /// , as this should only be done once to ensure accuracy. diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f833aa2bb7..5bf54877fc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Play [Cached] [Cached(Type = typeof(IBindable>))] - protected readonly Bindable> Mods = new Bindable>(Array.Empty()); + protected new readonly Bindable> Mods = new Bindable>(Array.Empty()); private readonly bool allowPause; private readonly bool showResults; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6a55fe278b..ebc6459abe 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -320,7 +320,6 @@ namespace osu.Game.Screens.Play private readonly Drawable facade; private LoadingAnimation loading; private Sprite backgroundSprite; - private ModDisplay modDisplay; public bool Loading { diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index a0f5969b3c..79c1a4cb6b 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -31,8 +31,6 @@ namespace osu.Game.Screens.Select.Carousel } } - private int creationOrder; - protected CarouselItem() { DrawableRepresentation = new Lazy(CreateDrawableRepresentation); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a78238c584..14c362b8ca 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -388,8 +388,6 @@ namespace osu.Game.Screens.Select { Logger.Log($"updating selection with beatmap:{beatmap?.ID.ToString() ?? "null"} ruleset:{ruleset?.ID.ToString() ?? "null"}"); - bool preview = false; - if (ruleset?.Equals(decoupledRuleset.Value) == false) { Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs new file mode 100644 index 0000000000..0e67a1897c --- /dev/null +++ b/osu.Game/Skinning/ISkin.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 System; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Skinning +{ + /// + /// Provides access to skinnable elements. + /// + public interface ISkin + { + Drawable GetDrawableComponent(string componentName); + + Texture GetTexture(string componentName); + + SampleChannel GetSample(string sampleName); + + TValue GetValue(Func query) where TConfiguration : SkinConfiguration; + } +} diff --git a/osu.Game/Skinning/ISkinSource.cs b/osu.Game/Skinning/ISkinSource.cs index 6d2b9e6fe2..337d2a87a4 100644 --- a/osu.Game/Skinning/ISkinSource.cs +++ b/osu.Game/Skinning/ISkinSource.cs @@ -2,25 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; -using osu.Framework.Audio.Sample; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Textures; namespace osu.Game.Skinning { /// /// Provides access to skinnable elements. /// - public interface ISkinSource + public interface ISkinSource : ISkin { event Action SourceChanged; - - Drawable GetDrawableComponent(string componentName); - - Texture GetTexture(string componentName); - - SampleChannel GetSample(string sampleName); - - TValue GetValue(Func query) where TConfiguration : SkinConfiguration; } } diff --git a/osu.Game/Skinning/LocalSkinOverrideContainer.cs b/osu.Game/Skinning/LocalSkinOverrideContainer.cs index 955ef7b65b..f1ed14595e 100644 --- a/osu.Game/Skinning/LocalSkinOverrideContainer.cs +++ b/osu.Game/Skinning/LocalSkinOverrideContainer.cs @@ -22,18 +22,18 @@ namespace osu.Game.Skinning private readonly Bindable beatmapSkins = new Bindable(); private readonly Bindable beatmapHitsounds = new Bindable(); - private readonly ISkinSource source; + private readonly ISkin skin; private ISkinSource fallbackSource; - public LocalSkinOverrideContainer(ISkinSource source) + public LocalSkinOverrideContainer(ISkin skin) { - this.source = source; + this.skin = skin; } public Drawable GetDrawableComponent(string componentName) { Drawable sourceDrawable; - if (beatmapSkins.Value && (sourceDrawable = source.GetDrawableComponent(componentName)) != null) + if (beatmapSkins.Value && (sourceDrawable = skin.GetDrawableComponent(componentName)) != null) return sourceDrawable; return fallbackSource?.GetDrawableComponent(componentName); @@ -42,7 +42,7 @@ namespace osu.Game.Skinning public Texture GetTexture(string componentName) { Texture sourceTexture; - if (beatmapSkins.Value && (sourceTexture = source.GetTexture(componentName)) != null) + if (beatmapSkins.Value && (sourceTexture = skin.GetTexture(componentName)) != null) return sourceTexture; return fallbackSource.GetTexture(componentName); @@ -51,7 +51,7 @@ namespace osu.Game.Skinning public SampleChannel GetSample(string sampleName) { SampleChannel sourceChannel; - if (beatmapHitsounds.Value && (sourceChannel = source.GetSample(sampleName)) != null) + if (beatmapHitsounds.Value && (sourceChannel = skin.GetSample(sampleName)) != null) return sourceChannel; return fallbackSource?.GetSample(sampleName); @@ -60,7 +60,7 @@ namespace osu.Game.Skinning public TValue GetValue(Func query) where TConfiguration : SkinConfiguration { TValue val; - if ((source as Skin)?.Configuration is TConfiguration conf) + if ((skin as Skin)?.Configuration is TConfiguration conf) if (beatmapSkins.Value && (val = query.Invoke(conf)) != null) return val; diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 1d14f9cd6a..09c0d3d0bc 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -8,14 +8,12 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Skinning { - public abstract class Skin : IDisposable, ISkinSource + public abstract class Skin : IDisposable, ISkin { public readonly SkinInfo SkinInfo; public virtual SkinConfiguration Configuration { get; protected set; } - public event Action SourceChanged; - public abstract Drawable GetDrawableComponent(string componentName); public abstract SampleChannel GetSample(string sampleName); diff --git a/osu.Game/Tests/Visual/AllPlayersTestCase.cs b/osu.Game/Tests/Visual/AllPlayersTestCase.cs index 3e1f408a16..6e78851e31 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestCase.cs +++ b/osu.Game/Tests/Visual/AllPlayersTestCase.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual { Player p = null; AddStep(r.Name, () => p = loadPlayerFor(r)); - AddUntilStep(() => + AddUntilStep("player loaded", () => { if (p?.IsLoaded == true) { @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual } return false; - }, "player loaded"); + }); AddCheckSteps(); } diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 7f36a0e142..c71c2ae857 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual public abstract class EditorClockTestCase : OsuTestCase { protected readonly BindableBeatDivisor BeatDivisor = new BindableBeatDivisor(); - protected readonly EditorClock Clock; + protected new readonly EditorClock Clock; protected EditorClockTestCase() { diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index c08a6a4bcb..1f475209a4 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual [Cached(Type = typeof(IBindable>))] protected readonly Bindable> Mods = new Bindable>(Array.Empty()); - protected DependencyContainer Dependencies { get; private set; } + protected new DependencyContainer Dependencies { get; private set; } private readonly Lazy localStorage; protected Storage LocalStorage => localStorage.Value; diff --git a/osu.Game/Tests/Visual/PlayerTestCase.cs b/osu.Game/Tests/Visual/PlayerTestCase.cs index fca4fccae0..b9c7933cfb 100644 --- a/osu.Game/Tests/Visual/PlayerTestCase.cs +++ b/osu.Game/Tests/Visual/PlayerTestCase.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual public void SetUpSteps() { AddStep(ruleset.RulesetInfo.Name, loadPlayer); - AddUntilStep(() => Player.IsLoaded && Player.Alpha == 1, "player loaded"); + AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); } protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 22afce9c86..e25921c486 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -5,7 +5,6 @@ Library AnyCPU true - 0 From 1766ed8f9e2d28de824a20432c79e050d012dc34 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 18:05:46 +0900 Subject: [PATCH 240/278] Fix warnings/remove obsolete usages --- .../Profile/Header/BottomHeaderContainer.cs | 8 ++++---- .../Profile/Header/DetailHeaderContainer.cs | 3 +-- osu.Game/Overlays/Profile/Header/RankGraph.cs | 12 ++++-------- .../Overlays/Profile/Header/TopHeaderContainer.cs | 15 +++++---------- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ---- 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 04b70ea10f..9eb6feec8e 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 10), Children = new Drawable[] { - bottomTopLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + bottomTopLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, }, - bottomLinkContainer = new LinkFlowContainer(text => text.TextSize = 12) + bottomLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - void bold(SpriteText t) => t.Font = @"Exo2.0-Bold"; + void bold(SpriteText t) => t.Font = t.Font.With(weight: FontWeight.Bold); void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); bottomTopLinkContainer.Clear(); @@ -113,7 +113,7 @@ namespace osu.Game.Overlays.Profile.Header bottomLinkContainer.AddIcon(icon, text => { - text.TextSize = 10; + text.Font = text.Font.With(size: 10); text.Colour = communityUserGrayGreenLighter; }); if (link != null) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 19894f0301..84611b3bf1 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -213,8 +213,7 @@ namespace osu.Game.Overlays.Profile.Header }, rankCount = new OsuSpriteText { - Font = "Exo2.0-Bold", - TextSize = 12, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre } diff --git a/osu.Game/Overlays/Profile/Header/RankGraph.cs b/osu.Game/Overlays/Profile/Header/RankGraph.cs index 01f16fe942..d66f2306a0 100644 --- a/osu.Game/Overlays/Profile/Header/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/RankGraph.cs @@ -43,8 +43,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.Centre, Origin = Anchor.Centre, Text = "No recent plays", - TextSize = 12, - Font = @"Exo2.0-Regular", + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular) }, graph = new RankChartLineGraph { @@ -227,14 +226,12 @@ namespace osu.Game.Overlays.Profile.Header { new OsuSpriteText { - Font = "Exo2.0-Bold", - TextSize = 12, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Text = "Global Ranking " }, globalRankingText = new OsuSpriteText { - Font = "Exo2.0-Regular", - TextSize = 12, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, } @@ -242,8 +239,7 @@ namespace osu.Game.Overlays.Profile.Header }, timeText = new OsuSpriteText { - TextSize = 12, - Font = "Exo2.0-Regular" + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), } } } diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 8e4d72c702..80721af42f 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -75,8 +75,7 @@ namespace osu.Game.Overlays.Profile.Header { usernameText = new OsuSpriteText { - Font = "Exo2.0-Regular", - TextSize = 24 + Font = OsuFont.GetFont(size: 24, weight: FontWeight.Regular) }, openUserExternally = new ExternalLinkButton { @@ -96,8 +95,7 @@ namespace osu.Game.Overlays.Profile.Header { titleText = new OsuSpriteText { - TextSize = 18, - Font = "Exo2.0-Regular" + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Regular) }, supporterTag = new SupporterIcon { @@ -123,8 +121,7 @@ namespace osu.Game.Overlays.Profile.Header }, userCountryText = new OsuSpriteText { - Font = "Exo2.0-Regular", - TextSize = 17.5f, + Font = OsuFont.GetFont(size: 17.5f, weight: FontWeight.Regular), Margin = new MarginPadding { Left = 40 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, @@ -185,17 +182,15 @@ namespace osu.Game.Overlays.Profile.Header { new OsuSpriteText { - TextSize = 15, + Font = OsuFont.GetFont(size: 15), Text = left, - Font = "Exo2.0-Medium" }, new OsuSpriteText { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - TextSize = 15, + Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), Text = right, - Font = "Exo2.0-Bold" }, }; } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 776fcbb8b7..6238d1bc53 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -12,7 +12,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Profile @@ -29,9 +28,6 @@ namespace osu.Game.Overlays.Profile { CenterHeaderContainer centerHeaderContainer; DetailHeaderContainer detailHeaderContainer; - Container expandedDetailContainer; - FillFlowContainer hiddenDetailContainer, headerDetailContainer; - SpriteIcon expandButtonIcon; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From b33c0e9a9337763df37951623d29705d132b5f5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 18:42:19 +0900 Subject: [PATCH 241/278] Cleanup bottom header container --- .../Online/TestCaseUserProfileHeader.cs | 1 + .../Profile/Header/BottomHeaderContainer.cs | 108 +++++++++--------- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index 98bad9831f..bc2ff708c5 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -21,6 +21,7 @@ namespace osu.Game.Tests.Visual.Online typeof(RankGraph), typeof(LineGraph), typeof(ProfileHeaderTabControl), + typeof(BottomHeaderContainer) }; [Resolved] diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 9eb6feec8e..39dd1bd028 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -20,18 +20,21 @@ namespace osu.Game.Overlays.Profile.Header { public class BottomHeaderContainer : CompositeDrawable { - private LinkFlowContainer bottomTopLinkContainer; - private LinkFlowContainer bottomLinkContainer; - private Color4 linkBlue, communityUserGrayGreenLighter; - public readonly Bindable User = new Bindable(); + private LinkFlowContainer topLinkContainer; + private LinkFlowContainer bottomLinkContainer; + + private Color4 iconColour; + + public BottomHeaderContainer() + { + AutoSizeAxes = Axes.Y; + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { - AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); - InternalChildren = new Drawable[] { new Box @@ -48,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 10), Children = new Drawable[] { - bottomTopLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) + topLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -62,80 +65,55 @@ namespace osu.Game.Overlays.Profile.Header } }; - linkBlue = colours.BlueLight; - communityUserGrayGreenLighter = colours.CommunityUserGrayGreenLighter; + iconColour = colours.CommunityUserGrayGreenLighter; + + User.BindValueChanged(user => updateDisplay(user.NewValue)); } private void updateDisplay(User user) { - void bold(SpriteText t) => t.Font = t.Font.With(weight: FontWeight.Bold); - void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); - - bottomTopLinkContainer.Clear(); + topLinkContainer.Clear(); bottomLinkContainer.Clear(); if (user == null) return; if (user.JoinDate.ToUniversalTime().Year < 2008) - { - bottomTopLinkContainer.AddText("Here since the beginning"); - } + topLinkContainer.AddText("Here since the beginning"); else { - bottomTopLinkContainer.AddText("Joined "); - bottomTopLinkContainer.AddText(new DrawableDate(user.JoinDate), bold); + topLinkContainer.AddText("Joined "); + topLinkContainer.AddText(new DrawableDate(user.JoinDate), embolden); } - addSpacer(bottomTopLinkContainer); + addSpacer(topLinkContainer); if (user.PlayStyles?.Length > 0) { - bottomTopLinkContainer.AddText("Plays with "); - bottomTopLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), bold); + topLinkContainer.AddText("Plays with "); + topLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), embolden); - addSpacer(bottomTopLinkContainer); + addSpacer(topLinkContainer); } if (user.LastVisit.HasValue) { - bottomTopLinkContainer.AddText("Last seen "); - bottomTopLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), bold); + topLinkContainer.AddText("Last seen "); + topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); - addSpacer(bottomTopLinkContainer); + addSpacer(topLinkContainer); } - bottomTopLinkContainer.AddText("Contributed "); - bottomTopLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: bold); - - void tryAddInfo(IconUsage icon, string content, string link = null) - { - if (string.IsNullOrEmpty(content)) return; - - bottomLinkContainer.AddIcon(icon, text => - { - text.Font = text.Font.With(size: 10); - text.Colour = communityUserGrayGreenLighter; - }); - if (link != null) - { - bottomLinkContainer.AddLink(" " + content, link, creationParameters: text => - { - bold(text); - text.Colour = linkBlue; - }); - } - else - bottomLinkContainer.AddText(" " + content, bold); - - addSpacer(bottomLinkContainer); - } + topLinkContainer.AddText("Contributed "); + topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); string websiteWithoutProtcol = user.Website; if (!string.IsNullOrEmpty(websiteWithoutProtcol)) { - int protocolIndex = websiteWithoutProtcol.IndexOf("//", StringComparison.Ordinal); - if (protocolIndex >= 0) - websiteWithoutProtcol = websiteWithoutProtcol.Substring(protocolIndex + 2); + if (Uri.TryCreate(websiteWithoutProtcol, UriKind.Absolute, out var uri)) + { + websiteWithoutProtcol = uri.Host + uri.PathAndQuery + uri.Fragment; + websiteWithoutProtcol = websiteWithoutProtcol.TrimEnd('/'); + } } tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); @@ -149,5 +127,27 @@ namespace osu.Game.Overlays.Profile.Header tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtcol, user.Website); } + + private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); + + private void tryAddInfo(IconUsage icon, string content, string link = null) + { + if (string.IsNullOrEmpty(content)) return; + + bottomLinkContainer.AddIcon(icon, text => + { + text.Font = text.Font.With(size: 10); + text.Colour = iconColour; + }); + + if (link != null) + bottomLinkContainer.AddLink(" " + content, link, creationParameters: embolden); + else + bottomLinkContainer.AddText(" " + content, embolden); + + addSpacer(bottomLinkContainer); + } + + private void embolden(SpriteText text) => text.Font = text.Font.With(weight: FontWeight.Bold); } } From 0eca9b9683e25c81f6d509d9bd8f749967ca56ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 18:43:29 +0900 Subject: [PATCH 242/278] Center -> centre --- osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs | 1 + .../{CenterHeaderContainer.cs => CentreHeaderContainer.cs} | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) rename osu.Game/Overlays/Profile/Header/{CenterHeaderContainer.cs => CentreHeaderContainer.cs} (99%) diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index bc2ff708c5..531f30de83 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -21,6 +21,7 @@ namespace osu.Game.Tests.Visual.Online typeof(RankGraph), typeof(LineGraph), typeof(ProfileHeaderTabControl), + typeof(CentreHeaderContainer), typeof(BottomHeaderContainer) }; diff --git a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs similarity index 99% rename from osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs rename to osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 3d0b9b9db4..0ad343bb7e 100644 --- a/osu.Game/Overlays/Profile/Header/CenterHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class CenterHeaderContainer : CompositeDrawable + public class CentreHeaderContainer : CompositeDrawable { public Action DetailsVisibilityAction; private bool detailsVisible; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 6238d1bc53..3e257e19bf 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile public ProfileHeader() { - CenterHeaderContainer centerHeaderContainer; + CentreHeaderContainer centreHeaderContainer; DetailHeaderContainer detailHeaderContainer; RelativeSizeAxes = Axes.X; @@ -91,7 +91,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, - centerHeaderContainer = new CenterHeaderContainer + centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, User = { BindTarget = User }, @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Info"); infoTabControl.AddItem("Modding"); - centerHeaderContainer.DetailsVisibilityAction = visible => detailHeaderContainer.Alpha = visible ? 0 : 1; + centreHeaderContainer.DetailsVisibilityAction = visible => detailHeaderContainer.Alpha = visible ? 0 : 1; User.ValueChanged += e => updateDisplay(e.NewValue); } From 9d5b81165e4432b8e8299b43f8fd2c63ba8eab2a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 19:51:05 +0900 Subject: [PATCH 243/278] Adjust button stylings --- .../Visual/Online/TestCaseUserProfileHeader.cs | 3 ++- .../Profile/Header/CentreHeaderContainer.cs | 15 +++++++++++++-- .../Profile/Header/ProfileHeaderButton.cs | 7 ++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index 531f30de83..e425c25787 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -22,7 +22,8 @@ namespace osu.Game.Tests.Visual.Online typeof(LineGraph), typeof(ProfileHeaderTabControl), typeof(CentreHeaderContainer), - typeof(BottomHeaderContainer) + typeof(BottomHeaderContainer), + typeof(ProfileHeaderButton) }; [Resolved] diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 0ad343bb7e..658dd79570 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -4,6 +4,7 @@ using System; 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; @@ -104,7 +105,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Y, Padding = new MarginPadding { Vertical = 10 }, Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = detailsToggleButton = new ProfileHeaderButton + Child = detailsToggleButton = new ExpandButton { RelativeSizeAxes = Axes.Y, Anchor = Anchor.Centre, @@ -115,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(20), + Size = new Vector2(20, 12), Icon = FontAwesome.Solid.ChevronUp, }, } @@ -230,5 +231,15 @@ namespace osu.Game.Overlays.Profile.Header hiddenDetailGlobal.Content = user.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; hiddenDetailCountry.Content = user.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; } + + private class ExpandButton : ProfileHeaderButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IdleColour = colours.CommunityUserGrayGreen; + HoverColour = colours.CommunityUserGrayGreen.Darken(0.2f); + } + } } } diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs index 6d9ab7a4d8..e8c8788a10 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs @@ -2,10 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osuTK.Graphics; @@ -22,8 +22,9 @@ namespace osu.Game.Overlays.Profile.Header public ProfileHeaderButton() { - HoverColour = Color4.Black.Opacity(0.75f); - IdleColour = Color4.Black.Opacity(0.7f); + IdleColour = Color4.Black; + HoverColour = OsuColour.Gray(0.1f); + AutoSizeAxes = Axes.X; base.Content.Add(new CircularContainer From c6b3197dd0081aec6db80a2b1c7f00cb13124866 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 25 Apr 2019 13:56:57 +0300 Subject: [PATCH 244/278] Add AdjustRank and use it in Hidden Mod --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 3 ++ .../Visual/Gameplay/TestCasePlayerLoader.cs | 3 ++ .../Mods/IApplicableToScoreProcessor.cs | 3 ++ osu.Game/Rulesets/Mods/ModFlashlight.cs | 3 ++ osu.Game/Rulesets/Mods/ModHidden.cs | 18 +++++++++- osu.Game/Rulesets/Mods/ModSuddenDeath.cs | 3 ++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 34 ++++++++----------- osu.Game/Screens/Play/Player.cs | 2 ++ 8 files changed, 48 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index f3c7939a94..445f81c6d4 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -12,6 +12,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osuTK; using osuTK.Graphics; @@ -41,6 +42,8 @@ namespace osu.Game.Rulesets.Osu.Mods scoreProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); }; } + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + /// /// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency. /// diff --git a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs index f58c0d35b3..425d8fcda1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCasePlayerLoader.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; using osu.Game.Screens; using osu.Game.Screens.Play; @@ -110,6 +111,8 @@ namespace osu.Game.Tests.Visual.Gameplay { Applied = true; } + + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; } private class TestPlayer : Player diff --git a/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs b/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs index 1d0ed94ef4..34e8d858f6 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; namespace osu.Game.Rulesets.Mods { @@ -11,5 +12,7 @@ namespace osu.Game.Rulesets.Mods public interface IApplicableToScoreProcessor : IApplicableMod { void ApplyToScoreProcessor(ScoreProcessor scoreProcessor); + + ScoreRank AdjustRank(ScoreRank rank, double accuracy); } } diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 0ad99d13ff..f47306d16e 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osuTK; using osuTK.Graphics; @@ -46,6 +47,8 @@ namespace osu.Game.Rulesets.Mods Combo.BindTo(scoreProcessor.Combo); } + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { var flashlight = CreateFlashlight(); diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 389edb5a35..c55c45c9fa 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -9,6 +9,7 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; namespace osu.Game.Rulesets.Mods { @@ -35,7 +36,22 @@ namespace osu.Game.Rulesets.Mods public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - scoreProcessor.AdjustRank = true; + // Default value of ScoreProcessor's Rank in Hidden Mod should bes SS+ + scoreProcessor.Rank.Value = ScoreRank.XH; + } + + // TODO: Other mods that uses AdjustRank might have some issues due to rank changes + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) + { + switch (rank) + { + case ScoreRank.X: + return ScoreRank.XH; + case ScoreRank.S: + return ScoreRank.SH; + default: + return rank; + } } protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) diff --git a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs index 6a82050d26..809661db8e 100644 --- a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs +++ b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; namespace osu.Game.Rulesets.Mods { @@ -24,6 +25,8 @@ namespace osu.Game.Rulesets.Mods scoreProcessor.FailConditions += FailCondition; } + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + protected virtual bool FailCondition(ScoreProcessor scoreProcessor) => scoreProcessor.Combo.Value == 0; } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b1cd78dde6..9f31cb8d7c 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -7,9 +7,11 @@ using System.Diagnostics; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.TypeExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; using osu.Game.Scoring; @@ -60,6 +62,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt Combo = new BindableInt(); + /// + /// The current selected mods + /// + public readonly Bindable> Mods = new Bindable>(Array.Empty()); + /// /// Create a for this processor. /// @@ -95,34 +102,22 @@ namespace osu.Game.Rulesets.Scoring /// protected virtual bool DefaultFailCondition => Health.Value == Health.MinValue; - private bool adjustRank; - - /// - /// Used by specific mods to adjust . - /// - public bool AdjustRank - { - get => adjustRank; - - set - { - adjustRank = value; - Rank.Value = rankFrom(Accuracy.Value); // Update rank immediately if AdjustRank was changed - } - } - protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; - Accuracy.ValueChanged += delegate { Rank.Value = rankFrom(Accuracy.Value); }; + Accuracy.ValueChanged += delegate + { + foreach (var mod in Mods.Value.OfType()) + Rank.Value = mod.AdjustRank(rankFrom(Accuracy.Value), Accuracy.Value); + }; } private ScoreRank rankFrom(double acc) { if (acc == 1) - return (adjustRank ? ScoreRank.XH : ScoreRank.X); + return ScoreRank.X; if (acc > 0.95) - return (adjustRank ? ScoreRank.SH : ScoreRank.S); + return ScoreRank.S; if (acc > 0.9) return ScoreRank.A; if (acc > 0.8) @@ -146,7 +141,6 @@ namespace osu.Game.Rulesets.Scoring Rank.Value = ScoreRank.X; HighestCombo.Value = 0; - AdjustRank = false; HasFailed = false; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f833aa2bb7..5e2880e24b 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -106,6 +106,8 @@ namespace osu.Game.Screens.Play showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); ScoreProcessor = DrawableRuleset.CreateScoreProcessor(); + ScoreProcessor.Mods.BindTo(Mods); + if (!ScoreProcessor.Mode.Disabled) config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); From 2caea38f8c4f4e672a12197d03aee73e18e646cc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 20:05:59 +0900 Subject: [PATCH 245/278] Cleanup centre header container --- .../Profile/Header/BottomHeaderContainer.cs | 4 +-- .../Profile/Header/CentreHeaderContainer.cs | 36 ++++++++++--------- .../Profile/Header/OverlinedInfoContainer.cs | 3 +- .../Profile/Header/ProfileHeaderButton.cs | 4 +-- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 39dd1bd028..f97fecb913 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -35,6 +35,8 @@ namespace osu.Game.Overlays.Profile.Header [BackgroundDependencyLoader] private void load(OsuColour colours) { + iconColour = colours.CommunityUserGrayGreenLighter; + InternalChildren = new Drawable[] { new Box @@ -65,8 +67,6 @@ namespace osu.Game.Overlays.Profile.Header } }; - iconColour = colours.CommunityUserGrayGreenLighter; - User.BindValueChanged(user => updateDisplay(user.NewValue)); } diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 658dd79570..935e25e4b8 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -21,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Header { public class CentreHeaderContainer : CompositeDrawable { - public Action DetailsVisibilityAction; - private bool detailsVisible; + public readonly BindableBool DetailsVisible = new BindableBool(true); + public readonly Bindable User = new Bindable(); private OsuSpriteText followerText; private OsuSpriteText levelBadgeText; @@ -30,18 +29,20 @@ namespace osu.Game.Overlays.Profile.Header private Bar levelProgressBar; private OsuSpriteText levelProgressText; - private OverlinedInfoContainer hiddenDetailGlobal, hiddenDetailCountry; + private OverlinedInfoContainer hiddenDetailGlobal; + private OverlinedInfoContainer hiddenDetailCountry; - public readonly Bindable User = new Bindable(); + public CentreHeaderContainer() + { + Height = 60; + } [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures) { - Container hiddenDetailContainer, expandedDetailContainer; + Container hiddenDetailContainer; + Container expandedDetailContainer; SpriteIcon expandButtonIcon; - ProfileHeaderButton detailsToggleButton; - Height = 60; - User.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -105,11 +106,12 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Y, Padding = new MarginPadding { Vertical = 10 }, Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = detailsToggleButton = new ExpandButton + Child = new ExpandButton { RelativeSizeAxes = Axes.Y, Anchor = Anchor.Centre, Origin = Anchor.Centre, + Action = () => DetailsVisible.Toggle(), Children = new Drawable[] { expandButtonIcon = new SpriteIcon @@ -210,14 +212,14 @@ namespace osu.Game.Overlays.Profile.Header } }; - detailsToggleButton.Action = () => + DetailsVisible.BindValueChanged(visible => { - detailsVisible = !detailsVisible; - expandButtonIcon.Icon = detailsVisible ? FontAwesome.Solid.ChevronDown : FontAwesome.Solid.ChevronUp; - hiddenDetailContainer.Alpha = detailsVisible ? 1 : 0; - expandedDetailContainer.Alpha = detailsVisible ? 0 : 1; - DetailsVisibilityAction(detailsVisible); - }; + expandButtonIcon.Icon = visible.NewValue ? FontAwesome.Solid.ChevronUp : FontAwesome.Solid.ChevronDown; + hiddenDetailContainer.Alpha = visible.NewValue ? 1 : 0; + expandedDetailContainer.Alpha = visible.NewValue ? 0 : 1; + }, true); + + User.BindValueChanged(user => updateDisplay(user.NewValue)); } private void updateDisplay(User user) diff --git a/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs index 6d15f96eea..2eb84c9d71 100644 --- a/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs @@ -13,7 +13,8 @@ namespace osu.Game.Overlays.Profile.Header public class OverlinedInfoContainer : CompositeDrawable { private readonly Circle line; - private readonly OsuSpriteText title, content; + private readonly OsuSpriteText title; + private readonly OsuSpriteText content; public string Title { diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs index e8c8788a10..300767cf0d 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs @@ -22,11 +22,11 @@ namespace osu.Game.Overlays.Profile.Header public ProfileHeaderButton() { + AutoSizeAxes = Axes.X; + IdleColour = Color4.Black; HoverColour = OsuColour.Gray(0.1f); - AutoSizeAxes = Axes.X; - base.Content.Add(new CircularContainer { Masking = true, diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 3e257e19bf..3ccf2af061 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Info"); infoTabControl.AddItem("Modding"); - centreHeaderContainer.DetailsVisibilityAction = visible => detailHeaderContainer.Alpha = visible ? 0 : 1; + centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Alpha = visible.NewValue ? 1 : 0, true); User.ValueChanged += e => updateDisplay(e.NewValue); } From 8329e53b6ceea408c7c13fb1153ba4b29f1d1a09 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 20:08:14 +0900 Subject: [PATCH 246/278] Remove extra space from header title --- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 3ccf2af061..d9557952df 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.Profile { public ProfileHeaderTitle() { - Title = "Player "; + Title = "Player"; Section = "Info"; } From f8c5ee457bcdc3f46215860d74c91fa3394340dd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 20:09:42 +0900 Subject: [PATCH 247/278] Reduce tabcontrol spacing --- osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index e7c9676550..c6b66b48d0 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Header public ProfileHeaderTabControl() { TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(20, 0); + TabContainer.Spacing = new Vector2(15, 0); AddInternal(bar = new Box { From 619071b7ee1fb4d241e264feeb22b32d43952e11 Mon Sep 17 00:00:00 2001 From: KingLuigi4932 Date: Thu, 25 Apr 2019 14:23:00 +0300 Subject: [PATCH 248/278] Unnecessary 'using' directive --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index a4ba541499..aed5631f0f 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.TypeExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; From 838325fed41503c00b909da2067bae8b2bb257c1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Apr 2019 20:30:16 +0900 Subject: [PATCH 249/278] Remove HasTooltipContainer, use separate composites --- .../Online/TestCaseUserProfileHeader.cs | 1 + .../Profile/Header/CentreHeaderContainer.cs | 55 ++------------- .../Profile/Header/DetailHeaderContainer.cs | 38 +--------- .../Overlays/Profile/Header/LevelBadge.cs | 57 +++++++++++++++ .../Profile/Header/LevelProgressBar.cs | 65 +++++++++++++++++ .../Profile/Header/OverlinedTotalPlayTime.cs | 69 +++++++++++++++++++ osu.Game/Overlays/Profile/ProfileHeader.cs | 6 -- 7 files changed, 201 insertions(+), 90 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/LevelBadge.cs create mode 100644 osu.Game/Overlays/Profile/Header/LevelProgressBar.cs create mode 100644 osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index e425c25787..0f1e954224 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -23,6 +23,7 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileHeaderTabControl), typeof(CentreHeaderContainer), typeof(BottomHeaderContainer), + typeof(DetailHeaderContainer), typeof(ProfileHeaderButton) }; diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 935e25e4b8..e10d259ca9 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -11,10 +11,8 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Users; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { @@ -24,11 +22,6 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); private OsuSpriteText followerText; - private OsuSpriteText levelBadgeText; - - private Bar levelProgressBar; - private OsuSpriteText levelProgressText; - private OverlinedInfoContainer hiddenDetailGlobal; private OverlinedInfoContainer hiddenDetailCountry; @@ -132,56 +125,24 @@ namespace osu.Game.Overlays.Profile.Header Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, Children = new Drawable[] { - new ProfileHeader.HasTooltipContainer + new LevelBadge { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - TooltipText = "Level", - Children = new Drawable[] - { - new Sprite - { - RelativeSizeAxes = Axes.Both, - Texture = textures.Get("Profile/levelbadge"), - Colour = colours.Yellow, - }, - levelBadgeText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 20) - } - } + User = { BindTarget = User } }, - expandedDetailContainer = new ProfileHeader.HasTooltipContainer + expandedDetailContainer = new Container { - TooltipText = "Progress to next level", Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Width = 200, Height = 6, Margin = new MarginPadding { Right = 50 }, - Children = new Drawable[] + Child = new LevelProgressBar { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = levelProgressBar = new Bar - { - RelativeSizeAxes = Axes.Both, - BackgroundColour = Color4.Black, - Direction = BarDirection.LeftToRight, - AccentColour = colours.Yellow - } - }, - levelProgressText = new OsuSpriteText - { - Anchor = Anchor.BottomRight, - Origin = Anchor.TopRight, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold) - } + RelativeSizeAxes = Axes.Both, + User = { BindTarget = User } } }, hiddenDetailContainer = new FillFlowContainer @@ -226,10 +187,6 @@ namespace osu.Game.Overlays.Profile.Header { followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - levelBadgeText.Text = user.Statistics?.Level.Current.ToString() ?? "0"; - levelProgressBar.Length = user.Statistics?.Level.Progress / 100f ?? 0; - levelProgressText.Text = user.Statistics?.Level.Progress.ToString("0'%'"); - hiddenDetailGlobal.Content = user.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; hiddenDetailCountry.Content = user.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 84611b3bf1..62e57fef79 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -20,8 +20,7 @@ namespace osu.Game.Overlays.Profile.Header { public class DetailHeaderContainer : CompositeDrawable { - private ProfileHeader.HasTooltipContainer totalPlayTimeTooltip; - private OverlinedInfoContainer totalPlayTimeInfo, medalInfo, ppInfo; + private OverlinedInfoContainer medalInfo, ppInfo; private readonly Dictionary scoreRankInfos = new Dictionary(); private OverlinedInfoContainer detailGlobalRank, detailCountryRank; private RankGraph rankGraph; @@ -65,15 +64,9 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(10, 0), Children = new Drawable[] { - totalPlayTimeTooltip = new ProfileHeader.HasTooltipContainer + new OverlinedTotalPlayTime { - AutoSizeAxes = Axes.Both, - TooltipText = "0 hours", - Child = totalPlayTimeInfo = new OverlinedInfoContainer - { - Title = "Total Play Time", - LineColour = colours.Yellow, - }, + User = { BindTarget = User } }, medalInfo = new OverlinedInfoContainer { @@ -149,31 +142,6 @@ namespace osu.Game.Overlays.Profile.Header medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToString("#,##0") ?? "0"; - string formatTime(int? secondsNull) - { - if (secondsNull == null) return "0h 0m"; - - int seconds = secondsNull.Value; - string time = ""; - - int days = seconds / 86400; - seconds -= days * 86400; - if (days > 0) - time += days + "d "; - - int hours = seconds / 3600; - seconds -= hours * 3600; - time += hours + "h "; - - int minutes = seconds / 60; - time += minutes + "m"; - - return time; - } - - totalPlayTimeInfo.Content = formatTime(user?.Statistics?.PlayTime); - totalPlayTimeTooltip.TooltipText = (user?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; - foreach (var scoreRankInfo in scoreRankInfos) scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; diff --git a/osu.Game/Overlays/Profile/Header/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/LevelBadge.cs new file mode 100644 index 0000000000..8990956811 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/LevelBadge.cs @@ -0,0 +1,57 @@ +// 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.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; + +namespace osu.Game.Overlays.Profile.Header +{ + public class LevelBadge : CompositeDrawable, IHasTooltip + { + public readonly Bindable User = new Bindable(); + + public string TooltipText { get; } + + private OsuSpriteText levelText; + + public LevelBadge() + { + TooltipText = "Level"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, TextureStore textures) + { + InternalChildren = new Drawable[] + { + new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get("Profile/levelbadge"), + Colour = colours.Yellow, + }, + levelText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 20) + } + }; + + User.BindValueChanged(updateLevel); + } + + private void updateLevel(ValueChangedEvent user) + { + levelText.Text = user.NewValue?.Statistics?.Level.Current.ToString() ?? "0"; + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs new file mode 100644 index 0000000000..20d30bd993 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs @@ -0,0 +1,65 @@ +// 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.Cursor; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Users; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Profile.Header +{ + public class LevelProgressBar : CompositeDrawable, IHasTooltip + { + public readonly Bindable User = new Bindable(); + + public string TooltipText { get; } + + private Bar levelProgressBar; + private OsuSpriteText levelProgressText; + + public LevelProgressBar() + { + TooltipText = "Progress to next level"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + InternalChildren = new Drawable[] + { + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = levelProgressBar = new Bar + { + RelativeSizeAxes = Axes.Both, + BackgroundColour = Color4.Black, + Direction = BarDirection.LeftToRight, + AccentColour = colours.Yellow + } + }, + levelProgressText = new OsuSpriteText + { + Anchor = Anchor.BottomRight, + Origin = Anchor.TopRight, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold) + } + }; + + User.BindValueChanged(updateProgress); + } + + private void updateProgress(ValueChangedEvent user) + { + levelProgressBar.Length = user.NewValue?.Statistics?.Level.Progress / 100f ?? 0; + levelProgressText.Text = user.NewValue?.Statistics?.Level.Progress.ToString("0'%'"); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs new file mode 100644 index 0000000000..80c25ef4e5 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs @@ -0,0 +1,69 @@ +// 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.Cursor; +using osu.Game.Graphics; +using osu.Game.Users; + +namespace osu.Game.Overlays.Profile.Header +{ + public class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip + { + public readonly Bindable User = new Bindable(); + + public string TooltipText { get; set; } + + private OverlinedInfoContainer info; + + public OverlinedTotalPlayTime() + { + AutoSizeAxes = Axes.Both; + + TooltipText = "0 hours"; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + InternalChild = info = new OverlinedInfoContainer + { + Title = "Total Play Time", + LineColour = colours.Yellow, + }; + + User.BindValueChanged(updateTime, true); + } + + private void updateTime(ValueChangedEvent user) + { + TooltipText = (user.NewValue?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; + info.Content = formatTime(user.NewValue?.Statistics?.PlayTime); + } + + private string formatTime(int? secondsNull) + { + if (secondsNull == null) return "0h 0m"; + + int seconds = secondsNull.Value; + string time = ""; + + int days = seconds / 86400; + seconds -= days * 86400; + if (days > 0) + time += days + "d "; + + int hours = seconds / 3600; + seconds -= hours * 3600; + time += hours + "h "; + + int minutes = seconds / 60; + time += minutes + "m"; + + return time; + } + } +} diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index d9557952df..7969c645ec 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; @@ -135,11 +134,6 @@ namespace osu.Game.Overlays.Profile coverContainer.User = user; } - public class HasTooltipContainer : Container, IHasTooltip - { - public string TooltipText { get; set; } - } - private class ProfileHeaderTitle : ScreenTitle { public ProfileHeaderTitle() From d5b91c6455b1fe9cae8ef37f98a2c4fffa6b3070 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 12:32:15 +0900 Subject: [PATCH 250/278] Cleanup top header container + user handling --- .../Profile/Header/CentreHeaderContainer.cs | 6 ++-- .../Overlays/Profile/Header/LevelBadge.cs | 6 ++-- .../Profile/Header/LevelProgressBar.cs | 8 ++--- .../Profile/Header/TopHeaderContainer.cs | 29 ++++++++++--------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index e10d259ca9..7964d25db6 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -185,10 +185,10 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - followerText.Text = user.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; + followerText.Text = user?.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - hiddenDetailGlobal.Content = user.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; - hiddenDetailCountry.Content = user.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; + hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; + hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; } private class ExpandButton : ProfileHeaderButton diff --git a/osu.Game/Overlays/Profile/Header/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/LevelBadge.cs index 8990956811..cc05926be4 100644 --- a/osu.Game/Overlays/Profile/Header/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/LevelBadge.cs @@ -46,12 +46,12 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(updateLevel); + User.BindValueChanged(user => updateLevel(user.NewValue)); } - private void updateLevel(ValueChangedEvent user) + private void updateLevel(User user) { - levelText.Text = user.NewValue?.Statistics?.Level.Current.ToString() ?? "0"; + levelText.Text = user?.Statistics?.Level.Current.ToString() ?? "0"; } } } diff --git a/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs index 20d30bd993..c043efb423 100644 --- a/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs @@ -53,13 +53,13 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(updateProgress); + User.BindValueChanged(user => updateProgress(user.NewValue)); } - private void updateProgress(ValueChangedEvent user) + private void updateProgress(User user) { - levelProgressBar.Length = user.NewValue?.Statistics?.Level.Progress / 100f ?? 0; - levelProgressText.Text = user.NewValue?.Statistics?.Level.Progress.ToString("0'%'"); + levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0; + levelProgressText.Text = user?.Statistics?.Level.Progress.ToString("0'%'"); } } } diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 80721af42f..50e19d430b 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -17,6 +17,10 @@ namespace osu.Game.Overlays.Profile.Header { public class TopHeaderContainer : CompositeDrawable { + private const float avatar_size = 110; + + public readonly Bindable User = new Bindable(); + private SupporterIcon supporterTag; private UpdateableAvatar avatar; private OsuSpriteText usernameText; @@ -26,15 +30,10 @@ namespace osu.Game.Overlays.Profile.Header private OsuSpriteText userCountryText; private FillFlowContainer userStats; - private const float avatar_size = 110; - - public readonly Bindable User = new Bindable(); - [BackgroundDependencyLoader] private void load(OsuColour colours) { Height = 150; - User.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -146,21 +145,23 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 2) } }; + + User.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateDisplay(User user) + private void updateUser(User user) { avatar.User = user; - usernameText.Text = user.Username; - openUserExternally.Link = $@"https://osu.ppy.sh/users/{user.Id}"; - userFlag.Country = user.Country; - userCountryText.Text = user.Country?.FullName ?? "Alien"; - supporterTag.SupporterLevel = user.SupportLevel; - titleText.Text = user.Title; - titleText.Colour = OsuColour.FromHex(user.Colour ?? "fff"); + usernameText.Text = user?.Username ?? string.Empty; + openUserExternally.Link = $@"https://osu.ppy.sh/users/{user?.Id ?? 0}"; + userFlag.Country = user?.Country; + userCountryText.Text = user?.Country?.FullName ?? "Alien"; + supporterTag.SupporterLevel = user?.SupportLevel ?? 0; + titleText.Text = user?.Title ?? string.Empty; + titleText.Colour = OsuColour.FromHex(user?.Colour ?? "fff"); userStats.Clear(); - if (user.Statistics != null) + if (user?.Statistics != null) { userStats.Add(new UserStatsLine("Ranked Score", user.Statistics.RankedScore.ToString("#,##0"))); userStats.Add(new UserStatsLine("Hit Accuracy", Math.Round(user.Statistics.Accuracy, 2).ToString("#0.00'%'"))); From 4adf590036e6b9a6674175e0a15870079601373b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 12:41:00 +0900 Subject: [PATCH 251/278] Combine hover/active state handling in tab control --- .../Profile/Header/ProfileHeaderTabControl.cs | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs index c6b66b48d0..3b16b102d5 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs @@ -24,10 +24,10 @@ namespace osu.Game.Overlays.Profile.Header get => accentColour; set { - if (accentColour == value) return; + if (accentColour == value) + return; accentColour = value; - bar.Colour = value; foreach (TabItem tabItem in TabContainer) @@ -76,10 +76,13 @@ namespace osu.Game.Overlays.Profile.Header get => accentColour; set { - accentColour = value; + if (accentColour == value) + return; + accentColour = value; bar.Colour = value; - if (!Active.Value) text.Colour = value; + + updateState(); } } @@ -112,37 +115,40 @@ namespace osu.Game.Overlays.Profile.Header protected override bool OnHover(HoverEvent e) { - if (!Active.Value) - onActivated(true); - return base.OnHover(e); + base.OnHover(e); + + updateState(); + + return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - if (!Active.Value) - OnDeactivated(); + updateState(); } - protected override void OnActivated() - { - onActivated(); - } + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - bar.ResizeHeightTo(0, 120, Easing.InQuad); - text.Font = text.Font.With(weight: FontWeight.Medium); - } + protected override void OnDeactivated() => updateState(); - private void onActivated(bool fake = false) + private void updateState() { - text.FadeColour(Color4.White, 120, Easing.InQuad); - bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); - if (!fake) - text.Font = text.Font.With(weight: FontWeight.Bold); + if (Active.Value || IsHovered) + { + text.FadeColour(Color4.White, 120, Easing.InQuad); + bar.ResizeHeightTo(7.5f, 120, Easing.InQuad); + + if (Active.Value) + text.Font = text.Font.With(weight: FontWeight.Bold); + } + else + { + text.FadeColour(AccentColour, 120, Easing.InQuad); + bar.ResizeHeightTo(0, 120, Easing.InQuad); + text.Font = text.Font.With(weight: FontWeight.Medium); + } } } } From 7047303b0fcf68378f6ea315570ab8a279d0061e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 13:29:58 +0900 Subject: [PATCH 252/278] Add tooltips to all buttons --- .../Profile/Header/CentreHeaderContainer.cs | 63 ++----------------- .../Profile/Header/ExpandDetailsButton.cs | 45 +++++++++++++ .../Overlays/Profile/Header/FriendButton.cs | 58 +++++++++++++++++ .../Profile/Header/ProfileHeaderButton.cs | 7 ++- .../Profile/Header/ProfileMessageButton.cs | 2 + 5 files changed, 114 insertions(+), 61 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs create mode 100644 osu.Game/Overlays/Profile/Header/FriendButton.cs diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 7964d25db6..1d947383a1 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -3,14 +3,11 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Users; using osuTK; @@ -21,7 +18,6 @@ namespace osu.Game.Overlays.Profile.Header public readonly BindableBool DetailsVisible = new BindableBool(true); public readonly Bindable User = new Bindable(); - private OsuSpriteText followerText; private OverlinedInfoContainer hiddenDetailGlobal; private OverlinedInfoContainer hiddenDetailCountry; @@ -35,7 +31,6 @@ namespace osu.Game.Overlays.Profile.Header { Container hiddenDetailContainer; Container expandedDetailContainer; - SpriteIcon expandButtonIcon; InternalChildren = new Drawable[] { @@ -54,37 +49,10 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(10, 0), Children = new Drawable[] { - new ProfileHeaderButton + new FriendButton { RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Padding = new MarginPadding { Right = 10 }, - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.Solid.User, - FillMode = FillMode.Fit, - Size = new Vector2(50, 14) - }, - followerText = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(weight: FontWeight.Bold) - } - } - } - } + User = { BindTarget = User } }, new ProfileMessageButton { @@ -99,22 +67,12 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Y, Padding = new MarginPadding { Vertical = 10 }, Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = new ExpandButton + Child = new ExpandDetailsButton { RelativeSizeAxes = Axes.Y, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = () => DetailsVisible.Toggle(), - Children = new Drawable[] - { - expandButtonIcon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(20, 12), - Icon = FontAwesome.Solid.ChevronUp, - }, - } + DetailsVisible = { BindTarget = DetailsVisible } }, }, new Container @@ -175,7 +133,6 @@ namespace osu.Game.Overlays.Profile.Header DetailsVisible.BindValueChanged(visible => { - expandButtonIcon.Icon = visible.NewValue ? FontAwesome.Solid.ChevronUp : FontAwesome.Solid.ChevronDown; hiddenDetailContainer.Alpha = visible.NewValue ? 1 : 0; expandedDetailContainer.Alpha = visible.NewValue ? 0 : 1; }, true); @@ -185,20 +142,8 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - followerText.Text = user?.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; - hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; } - - private class ExpandButton : ProfileHeaderButton - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - IdleColour = colours.CommunityUserGrayGreen; - HoverColour = colours.CommunityUserGrayGreen.Darken(0.2f); - } - } } } diff --git a/osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs new file mode 100644 index 0000000000..dc507be0b1 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class ExpandDetailsButton : ProfileHeaderButton + { + public readonly BindableBool DetailsVisible = new BindableBool(); + + public override string TooltipText => DetailsVisible.Value ? "collapse" : "expand"; + + private SpriteIcon icon; + + public ExpandDetailsButton() + { + Action = () => DetailsVisible.Toggle(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IdleColour = colours.CommunityUserGrayGreen; + HoverColour = colours.CommunityUserGrayGreen.Darken(0.2f); + + Child = icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20, 12) + }; + + DetailsVisible.BindValueChanged(visible => updateState(visible.NewValue), true); + } + + private void updateState(bool detailsVisible) => icon.Icon = detailsVisible ? FontAwesome.Solid.ChevronUp : FontAwesome.Solid.ChevronDown; + } +} diff --git a/osu.Game/Overlays/Profile/Header/FriendButton.cs b/osu.Game/Overlays/Profile/Header/FriendButton.cs new file mode 100644 index 0000000000..3b2f192fb1 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/FriendButton.cs @@ -0,0 +1,58 @@ +// 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.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class FriendButton : ProfileHeaderButton + { + public readonly Bindable User = new Bindable(); + + public override string TooltipText => "friends"; + + private OsuSpriteText followerText; + + [BackgroundDependencyLoader] + private void load() + { + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding { Right = 10 }, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.Solid.User, + FillMode = FillMode.Fit, + Size = new Vector2(50, 14) + }, + followerText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold) + } + } + }; + + User.BindValueChanged(user => updateFollowers(user.NewValue), true); + } + + private void updateFollowers(User user) => followerText.Text = user?.FollowerCount?.Length > 0 ? user.FollowerCount[0].ToString("#,##0") : "0"; + } +} diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs index 300767cf0d..ddf2338873 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -11,8 +12,10 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class ProfileHeaderButton : OsuHoverContainer + public abstract class ProfileHeaderButton : OsuHoverContainer, IHasTooltip { + public abstract string TooltipText { get; } + private readonly Box background; private readonly Container content; @@ -20,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header protected override IEnumerable EffectTargets => new[] { background }; - public ProfileHeaderButton() + protected ProfileHeaderButton() { AutoSizeAxes = Axes.X; diff --git a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs index 3121eae727..162d49cf1b 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs +++ b/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays.Profile.Header { public readonly Bindable User = new Bindable(); + public override string TooltipText => "send message"; + [Resolved(CanBeNull = true)] private ChannelManager channelManager { get; set; } From 2f4bf423a4d4ef4d56a91046ef4d0e70074188ee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 13:49:44 +0900 Subject: [PATCH 253/278] Renamespace --- osu.Game.Tests/Visual/Online/TestCaseRankGraph.cs | 2 +- osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs | 2 +- .../Visual/Online/TestCaseUserProfileHeader.cs | 1 + .../Overlays/Profile/Header/CentreHeaderContainer.cs | 5 +++-- .../{FriendButton.cs => Components/AddFriendButton.cs} | 4 ++-- .../Profile/Header/{ => Components}/DrawableBadge.cs | 2 +- .../Header/{ => Components}/ExpandDetailsButton.cs | 2 +- .../Profile/Header/{ => Components}/LevelBadge.cs | 2 +- .../Header/{ => Components}/LevelProgressBar.cs | 2 +- .../MessageUserButton.cs} | 6 +++--- .../Header/{ => Components}/OverlinedInfoContainer.cs | 2 +- .../Header/{ => Components}/OverlinedTotalPlayTime.cs | 2 +- .../Header/{ => Components}/ProfileHeaderButton.cs | 2 +- .../Profile/Header/{ => Components}/RankGraph.cs | 2 +- .../Profile/Header/{ => Components}/SupporterIcon.cs | 2 +- .../Overlays/Profile/Header/DetailHeaderContainer.cs | 1 + .../Overlays/Profile/Header/MedalHeaderContainer.cs | 1 + osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 1 + osu.Game/Overlays/Profile/ProfileHeader.cs | 10 +++++----- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- osu.Game/Users/UserPanel.cs | 2 +- 21 files changed, 30 insertions(+), 25 deletions(-) rename osu.Game/Overlays/Profile/Header/{FriendButton.cs => Components/AddFriendButton.cs} (94%) rename osu.Game/Overlays/Profile/Header/{ => Components}/DrawableBadge.cs (95%) rename osu.Game/Overlays/Profile/Header/{ => Components}/ExpandDetailsButton.cs (96%) rename osu.Game/Overlays/Profile/Header/{ => Components}/LevelBadge.cs (96%) rename osu.Game/Overlays/Profile/Header/{ => Components}/LevelProgressBar.cs (97%) rename osu.Game/Overlays/Profile/Header/{ProfileMessageButton.cs => Components/MessageUserButton.cs} (91%) rename osu.Game/Overlays/Profile/Header/{ => Components}/OverlinedInfoContainer.cs (97%) rename osu.Game/Overlays/Profile/Header/{ => Components}/OverlinedTotalPlayTime.cs (97%) rename osu.Game/Overlays/Profile/Header/{ => Components}/ProfileHeaderButton.cs (96%) rename osu.Game/Overlays/Profile/Header/{ => Components}/RankGraph.cs (99%) rename osu.Game/Overlays/Profile/Header/{ => Components}/SupporterIcon.cs (97%) diff --git a/osu.Game.Tests/Visual/Online/TestCaseRankGraph.cs b/osu.Game.Tests/Visual/Online/TestCaseRankGraph.cs index dff018bf91..a92b788e83 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseRankGraph.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; diff --git a/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs index c455c092ed..0789c14b32 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfile.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Overlays.Profile; -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.Tests/Visual/Online/TestCaseUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs index 0f1e954224..5f5ba89186 100644 --- a/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestCaseUserProfileHeader.cs @@ -9,6 +9,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile; 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/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 1d947383a1..c1ad2011f8 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; @@ -49,12 +50,12 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(10, 0), Children = new Drawable[] { - new FriendButton + new AddFriendButton { RelativeSizeAxes = Axes.Y, User = { BindTarget = User } }, - new ProfileMessageButton + new MessageUserButton { User = { BindTarget = User } }, diff --git a/osu.Game/Overlays/Profile/Header/FriendButton.cs b/osu.Game/Overlays/Profile/Header/Components/AddFriendButton.cs similarity index 94% rename from osu.Game/Overlays/Profile/Header/FriendButton.cs rename to osu.Game/Overlays/Profile/Header/Components/AddFriendButton.cs index 3b2f192fb1..2e4fd6fe3d 100644 --- a/osu.Game/Overlays/Profile/Header/FriendButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/AddFriendButton.cs @@ -11,9 +11,9 @@ using osu.Game.Graphics.Sprites; using osu.Game.Users; using osuTK; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { - public class FriendButton : ProfileHeaderButton + public class AddFriendButton : ProfileHeaderButton { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/DrawableBadge.cs b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs similarity index 95% rename from osu.Game/Overlays/Profile/Header/DrawableBadge.cs rename to osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs index 75a8f4e415..ea259fe49a 100644 --- a/osu.Game/Overlays/Profile/Header/DrawableBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs @@ -10,7 +10,7 @@ using osu.Framework.Graphics.Textures; using osu.Game.Users; using osuTK; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class DrawableBadge : CompositeDrawable, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs similarity index 96% rename from osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs rename to osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs index dc507be0b1..089228b2cd 100644 --- a/osu.Game/Overlays/Profile/Header/ExpandDetailsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osuTK; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class ExpandDetailsButton : ProfileHeaderButton { diff --git a/osu.Game/Overlays/Profile/Header/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs similarity index 96% rename from osu.Game/Overlays/Profile/Header/LevelBadge.cs rename to osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index cc05926be4..8069937810 100644 --- a/osu.Game/Overlays/Profile/Header/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Users; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class LevelBadge : CompositeDrawable, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/LevelProgressBar.cs rename to osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index c043efb423..6a6532764f 100644 --- a/osu.Game/Overlays/Profile/Header/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Users; using osuTK.Graphics; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class LevelProgressBar : CompositeDrawable, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs similarity index 91% rename from osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs rename to osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 162d49cf1b..cc6edcdd6a 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileMessageButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -10,9 +10,9 @@ using osu.Game.Online.Chat; using osu.Game.Users; using osuTK; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileMessageButton : ProfileHeaderButton + public class MessageUserButton : ProfileHeaderButton { public readonly Bindable User = new Bindable(); @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Profile.Header [Resolved] private IAPIProvider apiProvider { get; set; } - public ProfileMessageButton() + public MessageUserButton() { Content.Alpha = 0; RelativeSizeAxes = Axes.Y; diff --git a/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index 2eb84c9d71..c40ddca688 100644 --- a/osu.Game/Overlays/Profile/Header/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK.Graphics; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class OverlinedInfoContainer : CompositeDrawable { diff --git a/osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs rename to osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 80c25ef4e5..2c88a83680 100644 --- a/osu.Game/Overlays/Profile/Header/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Cursor; using osu.Game.Graphics; using osu.Game.Users; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs similarity index 96% rename from osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs rename to osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs index ddf2338873..1650f11523 100644 --- a/osu.Game/Overlays/Profile/Header/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osuTK.Graphics; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public abstract class ProfileHeaderButton : OsuHoverContainer, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs similarity index 99% rename from osu.Game/Overlays/Profile/Header/RankGraph.cs rename to osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index d66f2306a0..bb54d0ac51 100644 --- a/osu.Game/Overlays/Profile/Header/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -17,7 +17,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Users; using osuTK; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class RankGraph : Container, IHasCustomTooltip { diff --git a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs similarity index 97% rename from osu.Game/Overlays/Profile/Header/SupporterIcon.cs rename to osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index 569ed252b7..99b45aca93 100644 --- a/osu.Game/Overlays/Profile/Header/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class SupporterIcon : CompositeDrawable, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 62e57fef79..89a9d7ddd1 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Scoring; using osu.Game.Users; using osuTK; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 69b1203b9f..1e214b2d0c 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; using osuTK.Graphics; diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 50e19d430b..ce02e61d82 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 7969c645ec..f5233cf70c 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -2,16 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Overlays.Profile.Header; -using osu.Game.Users; 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.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Profile.Header; +using osu.Game.Users; namespace osu.Game.Overlays.Profile { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 6da736432f..4d891384e8 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -2,13 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; -using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Users; +using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Profile diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index eb7f0941fb..1a10e035cd 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -18,7 +18,7 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; namespace osu.Game.Users { From 50a775145cb3eb8de776799c35ae35f1c03715d6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 13:56:26 +0900 Subject: [PATCH 254/278] Separate variables --- osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 89a9d7ddd1..9bb0affe7d 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -21,9 +21,11 @@ namespace osu.Game.Overlays.Profile.Header { public class DetailHeaderContainer : CompositeDrawable { - private OverlinedInfoContainer medalInfo, ppInfo; private readonly Dictionary scoreRankInfos = new Dictionary(); - private OverlinedInfoContainer detailGlobalRank, detailCountryRank; + private OverlinedInfoContainer medalInfo; + private OverlinedInfoContainer ppInfo; + private OverlinedInfoContainer detailGlobalRank; + private OverlinedInfoContainer detailCountryRank; private RankGraph rankGraph; public readonly Bindable User = new Bindable(); From 32e71a6314c485107d24a9de9e2e4598d246fe88 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 26 Apr 2019 16:15:42 +0900 Subject: [PATCH 255/278] Fix incorrect seeking behaviour of TrackVirtualManual --- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 78f9103a74..c558275f62 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets; +using osuTK; namespace osu.Game.Tests.Beatmaps { @@ -67,9 +68,10 @@ namespace osu.Game.Tests.Beatmaps public override bool Seek(double seek) { - offset = Math.Min(seek, Length); + offset = MathHelper.Clamp(seek, 0, Length); lastReferenceTime = null; - return true; + + return offset == seek; } public override void Start() From 41d0b00120c9da14bbbac7fb514e64e779cb6ab0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 27 Apr 2019 16:43:23 +0900 Subject: [PATCH 256/278] Update framework --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 74ed9f91dd..3b47005049 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -16,7 +16,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9fff64c61c..20810886f3 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From 27c1c368ac715470e22b8dccfc5b42eed2745464 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 27 Apr 2019 20:31:00 +0900 Subject: [PATCH 257/278] Remove unused using --- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index fd65d8f9cc..d72c334ed3 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.UI; From 27ba89444ee7af1a82988fea3b3ecae91e7f1d8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 28 Apr 2019 01:08:14 +0900 Subject: [PATCH 258/278] Remove unnecessary using statements --- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 8c220b2cb4..f5233cf70c 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -12,8 +12,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; -using Humanizer; -using osu.Framework.Graphics.Effects; namespace osu.Game.Overlays.Profile { From 8ab514933673967a02ee873cb34d40755ceac527 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 28 Apr 2019 20:11:36 +0900 Subject: [PATCH 259/278] SupporterLevel -> SupportLevel --- osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs | 2 +- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 2 +- osu.Game/Users/UserPanel.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index 99b45aca93..d4ccef8b69 100644 --- a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components public string TooltipText => "osu!supporter"; - public int SupporterLevel + public int SupportLevel { set { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index ce02e61d82..c1fe430bdd 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -157,7 +157,7 @@ namespace osu.Game.Overlays.Profile.Header openUserExternally.Link = $@"https://osu.ppy.sh/users/{user?.Id ?? 0}"; userFlag.Country = user?.Country; userCountryText.Text = user?.Country?.FullName ?? "Alien"; - supporterTag.SupporterLevel = user?.SupportLevel ?? 0; + supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = OsuColour.FromHex(user?.Colour ?? "fff"); diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 75069273a5..47571b673d 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -191,7 +191,7 @@ namespace osu.Game.Users infoContainer.Add(new SupporterIcon { Height = 20f, - SupporterLevel = user.SupportLevel + SupportLevel = user.SupportLevel }); } From f9f6e1f04ae8cfbc3d1851a7746814baf5b189e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 28 Apr 2019 20:13:28 +0900 Subject: [PATCH 260/278] Clamp values to avoid potentially weird element --- .../Overlays/Profile/Header/Components/SupporterIcon.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index d4ccef8b69..cb12a62702 100644 --- a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; +using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { @@ -23,7 +24,9 @@ namespace osu.Game.Overlays.Profile.Header.Components { set { - if (value == 0) + int count = MathHelper.Clamp(value, 0, 3); + + if (count == 0) { content.Hide(); } @@ -31,7 +34,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { content.Show(); iconContainer.Clear(); - for (int i = 0; i < value; i++) + for (int i = 0; i < count; i++) { iconContainer.Add(new SpriteIcon { From 5d50316ae7565979ecb40604c74c7da0649b632c Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 30 Apr 2019 18:12:27 +0300 Subject: [PATCH 261/278] Add xmldoc --- osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs b/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs index 34e8d858f6..1b62dbdacf 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToScoreProcessor.cs @@ -13,6 +13,9 @@ namespace osu.Game.Rulesets.Mods { void ApplyToScoreProcessor(ScoreProcessor scoreProcessor); + /// + /// Adjusts a rank value passed by and returns it. + /// ScoreRank AdjustRank(ScoreRank rank, double accuracy); } } From 665558c297984e2a05590337440ee81bea864784 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Tue, 30 Apr 2019 18:44:06 +0300 Subject: [PATCH 262/278] Remove unnecessary comment --- osu.Game/Rulesets/Mods/ModHidden.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index c55c45c9fa..cda919c894 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -36,11 +36,10 @@ namespace osu.Game.Rulesets.Mods public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) { - // Default value of ScoreProcessor's Rank in Hidden Mod should bes SS+ + // Default value of public interface IApplicableToScoreProcessor : IApplicableMod { + /// + /// Provide a to a mod. Called once on initialisation of a play instance. + /// void ApplyToScoreProcessor(ScoreProcessor scoreProcessor); /// - /// Adjusts a rank value passed by and returns it. + /// Called every time a rank calculation is requested. Allows mods to adjust the final rank. /// ScoreRank AdjustRank(ScoreRank rank, double accuracy); } From c6992bd6f9d89e2670592d4e9264bd3dfc645ee7 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 2 May 2019 03:37:15 -0700 Subject: [PATCH 273/278] Switch hidden/expanded centre profile header information --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index c1ad2011f8..c2f1d5f2ad 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -134,8 +134,8 @@ namespace osu.Game.Overlays.Profile.Header DetailsVisible.BindValueChanged(visible => { - hiddenDetailContainer.Alpha = visible.NewValue ? 1 : 0; - expandedDetailContainer.Alpha = visible.NewValue ? 0 : 1; + hiddenDetailContainer.Alpha = visible.NewValue ? 0 : 1; + expandedDetailContainer.Alpha = visible.NewValue ? 1 : 0; }, true); User.BindValueChanged(user => updateDisplay(user.NewValue)); From ac31a9640a6f3f8df8f14edd2229f2d936b43dd0 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 2 May 2019 03:47:20 -0700 Subject: [PATCH 274/278] Add number sign to centre info rankings --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index c2f1d5f2ad..0642ef94df 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -143,8 +143,8 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("#,##0") ?? "-"; - hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("#,##0") ?? "-"; + hiddenDetailGlobal.Content = user?.Statistics?.Ranks.Global?.ToString("\\##,##0") ?? "-"; + hiddenDetailCountry.Content = user?.Statistics?.Ranks.Country?.ToString("\\##,##0") ?? "-"; } } } From 6bdaca1e3bf0a3ce4411a5d53f9ae64e80c8aec1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 3 May 2019 10:05:45 +0900 Subject: [PATCH 275/278] Fix mod equality checks not working as intended --- osu.Game/Online/API/Requests/Responses/APIMod.cs | 2 ++ osu.Game/Rulesets/Mods/IMod.cs | 3 ++- osu.Game/Rulesets/Mods/Mod.cs | 2 ++ osu.Game/Scoring/ScoreInfo.cs | 2 ++ osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs | 2 +- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIMod.cs b/osu.Game/Online/API/Requests/Responses/APIMod.cs index d7dda07b33..b9da4f49ee 100644 --- a/osu.Game/Online/API/Requests/Responses/APIMod.cs +++ b/osu.Game/Online/API/Requests/Responses/APIMod.cs @@ -8,5 +8,7 @@ namespace osu.Game.Online.API.Requests.Responses public class APIMod : IMod { public string Acronym { get; set; } + + public bool Equals(IMod other) => Acronym == other?.Acronym; } } diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index 448ad0eb30..a5e19f293c 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -1,11 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using Newtonsoft.Json; namespace osu.Game.Rulesets.Mods { - public interface IMod + public interface IMod : IEquatable { /// /// The shortened name of this mod. diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index d2d0a5bb26..023d37497a 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -70,5 +70,7 @@ namespace osu.Game.Rulesets.Mods /// Creates a copy of this initialised to a default state. /// public virtual Mod CreateCopy() => (Mod)Activator.CreateInstance(GetType()); + + public bool Equals(IMod other) => GetType() == other?.GetType(); } } diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index d36f963016..8bdc30ac94 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -177,6 +177,8 @@ namespace osu.Game.Scoring protected class DeserializedMod : IMod { public string Acronym { get; set; } + + public bool Equals(IMod other) => Acronym == other?.Acronym; } public override string ToString() => $"{User} playing {Beatmap}"; diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 9692dc513d..88c6fc5e2e 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Play if (ruleset.Value.ID != playlistItem.Ruleset.ID) throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset"); - if (!playlistItem.RequiredMods.All(m => Mods.Value.Contains(m))) + if (!playlistItem.RequiredMods.All(m => Mods.Value.Any(m.Equals))) throw new InvalidOperationException("Current Mods do not match PlaylistItem's RequiredMods"); var req = new CreateRoomScoreRequest(roomId.Value ?? 0, playlistItem.ID); From 0fa02718786a0eefa063cce18e9e5351f509ab59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 4 May 2019 11:01:12 +0900 Subject: [PATCH 276/278] Add animation when collapsing or expanding the profile details section --- .../Profile/Header/CentreHeaderContainer.cs | 6 ++-- .../Profile/Header/DetailHeaderContainer.cs | 33 +++++++++++++++++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 0642ef94df..b441775393 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -134,9 +134,9 @@ namespace osu.Game.Overlays.Profile.Header DetailsVisible.BindValueChanged(visible => { - hiddenDetailContainer.Alpha = visible.NewValue ? 0 : 1; - expandedDetailContainer.Alpha = visible.NewValue ? 1 : 0; - }, true); + hiddenDetailContainer.FadeTo(visible.NewValue ? 0 : 1, 200, Easing.OutQuint); + expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); + }); User.BindValueChanged(user => updateDisplay(user.NewValue)); } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 8fcf2711dd..de710c5fcd 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,14 +26,40 @@ namespace osu.Game.Overlays.Profile.Header private OverlinedInfoContainer ppInfo; private OverlinedInfoContainer detailGlobalRank; private OverlinedInfoContainer detailCountryRank; + private FillFlowContainer fillFlow; private RankGraph rankGraph; public readonly Bindable User = new Bindable(); + private bool expanded = true; + + public bool Expanded + { + set + { + if (expanded == value) return; + + expanded = value; + + if (fillFlow == null) return; + + fillFlow.ClearTransforms(); + + if (expanded) + fillFlow.AutoSizeAxes = Axes.Y; + else + { + fillFlow.AutoSizeAxes = Axes.None; + fillFlow.ResizeHeightTo(0, 200, Easing.OutQuint); + } + } + } + [BackgroundDependencyLoader] private void load(OsuColour colours) { AutoSizeAxes = Axes.Y; + User.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] @@ -43,10 +69,13 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colours.CommunityUserGrayGreenDarkest, }, - new FillFlowContainer + fillFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + AutoSizeAxes = expanded ? Axes.Y : Axes.None, + AutoSizeDuration = 200, + AutoSizeEasing = Easing.OutQuint, + Masking = true, Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 20), diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f5233cf70c..2d8c47b11a 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Profile infoTabControl.AddItem("Info"); infoTabControl.AddItem("Modding"); - centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Alpha = visible.NewValue ? 1 : 0, true); + centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); User.ValueChanged += e => updateDisplay(e.NewValue); } From 7fdc79dd68f32d13456aaa64994881215cf21b41 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 5 May 2019 20:20:41 +0900 Subject: [PATCH 277/278] Improve skip boundary logic to be closer to expectations Supersedes #4693. Closes #4676. --- osu.Game/Screens/Play/SkipOverlay.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 738877232d..65cf5e51f3 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -38,6 +38,10 @@ namespace osu.Game.Screens.Play public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; protected override bool BlockPositionalInput => false; + /// + /// Displays a skip overlay, giving the user the ability to skip forward. + /// + /// The time at which gameplay begins to appear. public SkipOverlay(double startTime) { this.startTime = startTime; @@ -87,16 +91,21 @@ namespace osu.Game.Screens.Play }; } - private const double skip_required_cutoff = 3000; + /// + /// Duration before gameplay start time required before skip button displays. + /// + private const double skip_buffer = 1000; + private const double fade_time = 300; - private double beginFadeTime => startTime - skip_required_cutoff - fade_time; + private double beginFadeTime => startTime - fade_time; protected override void LoadComplete() { base.LoadComplete(); - if (startTime < skip_required_cutoff) + // skip is not required if there is no extra "empty" time to skip. + if (Clock.CurrentTime > beginFadeTime - skip_buffer) { Alpha = 0; Expire(); @@ -107,7 +116,7 @@ namespace osu.Game.Screens.Play using (BeginAbsoluteSequence(beginFadeTime)) this.FadeOut(fade_time); - button.Action = () => RequestSeek?.Invoke(startTime - skip_required_cutoff - fade_time); + button.Action = () => RequestSeek?.Invoke(beginFadeTime); displayTime = Time.Current; From f26a1cff6cc7b1666e450d190d2c54e57a860531 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 7 May 2019 12:14:57 +0900 Subject: [PATCH 278/278] Fix beatmap import crashing during room creation --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 6271693a6a..a69b3d87ae 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -206,7 +206,7 @@ namespace osu.Game.Screens.Multi.Match if (Beatmap.Value != beatmapManager.DefaultBeatmap) return; - if (Beatmap.Value == null) + if (CurrentItem.Value == null) return; // Try to retrieve the corresponding local beatmap