Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add badges to ProfileHeader #2407

Merged
merged 8 commits into from
Apr 18, 2018
Merged
2 changes: 1 addition & 1 deletion osu.Game.Tests/Visual/TestCaseRankGraph.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using osu.Game.Overlays.Profile;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
Expand All @@ -11,6 +10,7 @@
using System;
using NUnit.Framework;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Profile.Header;
using osu.Game.Users;

namespace osu.Game.Tests.Visual
Expand Down
61 changes: 43 additions & 18 deletions osu.Game.Tests/Visual/TestCaseUserProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Profile;
using osu.Game.Overlays.Profile.Header;
using osu.Game.Users;

namespace osu.Game.Tests.Visual
Expand All @@ -23,6 +24,7 @@ public class TestCaseUserProfile : OsuTestCase
typeof(UserProfileOverlay),
typeof(RankGraph),
typeof(LineGraph),
typeof(BadgeContainer)
};

public TestCaseUserProfile()
Expand All @@ -34,27 +36,24 @@ protected override void LoadComplete()
{
base.LoadComplete();

AddStep("Show offline dummy", () => profile.ShowUser(new User
AddStep("Show offline dummy", () => profile.ShowUser(createDummyUser(new Badge[0]), false));

AddStep("Show with badge", () => profile.ShowUser(createDummyUser(new[]
{
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,
Age = 1,
ProfileOrder = new[] { "me" },
Statistics = new UserStatistics
new Badge
{
Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 },
PP = 4567.89m,
},
RankHistory = new User.RankHistoryData
{
Mode = @"osu",
Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray()
AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569),
Description = "Outstanding help by being a voluntary test subject.",
ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg"
}
}, false));
}), false));

AddStep("Show many badges", () => profile.ShowUser(createDummyUser(Enumerable.Range(0, 10).Select(i => new Badge
{
AwardedAt = DateTimeOffset.Now,
Description = i.ToString(),
ImageUrl = "Flags/__"
}).ToArray()), false));

checkSupporterTag(false);

Expand Down Expand Up @@ -95,6 +94,32 @@ private void checkSupporterTag(bool isSupporter)
AddAssert("no supporter", () => profile.Header.SupporterTag.Alpha == 0);
}

private User createDummyUser(Badge[] badges)
{
return 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,
Age = 1,
ProfileOrder = new[] { "me" },
Statistics = new UserStatistics
{
Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 },
PP = 4567.89m,
},
RankHistory = new User.RankHistoryData
{
Mode = @"osu",
Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray()
},
Badges = badges
};
}

This comment was marked as off-topic.


private class TestUserProfileOverlay : UserProfileOverlay
{
public new ProfileHeader Header => base.Header;
Expand Down
190 changes: 190 additions & 0 deletions osu.Game/Overlays/Profile/Header/BadgeContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Users;
using OpenTK;

namespace osu.Game.Overlays.Profile.Header
{
public class BadgeContainer : Container
{
private const float outer_container_width = 98;
private const float outer_container_padding = 3;
private static readonly Vector2 badge_size = new Vector2(outer_container_width - outer_container_padding * 2, 46);

This comment was marked as off-topic.


private OsuSpriteText badgeCountText;
private FillFlowContainer badgeFlowContainer;
private FillFlowContainer outerBadgeContainer;

[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Child = new Container
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
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 = new MarginPadding(outer_container_padding),
Width = outer_container_width,
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(-badge_size.X * visibleBadge, 500, Easing.InOutQuad);
}

private int visibleBadge;
private int badgeCount;

public void ShowBadges(Badge[] badges)

This comment was marked as off-topic.

This comment was marked as off-topic.

{
switch (badges.Length)
{
case 0:
Hide();
return;
case 1:
badgeCountText.Hide();
break;
default:
badgeCountText.Show();
badgeCountText.Text = $"{badges.Length} badges";
break;
}

Show();
badgeCount = badges.Length;
visibleBadge = 0;

foreach (var badge in badges)
{
LoadComponentAsync(new DrawableBadge(badge)
{
Size = badge_size,
}, badgeFlowContainer.Add);
}
}

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()
{
rotateBadges();

This comment was marked as off-topic.

badgeFlowContainer.Direction = FillDirection.Horizontal;
outerBadgeContainer.AutoSizeAxes = Axes.Y;
outerBadgeContainer.Width = outer_container_width;
}

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(InputState state)
{
hoverAction();
return true;
}

protected override void OnHoverLost(InputState state) => hoverLostAction();
}

private class DrawableBadge : Container, IHasTooltip
{
private readonly Badge badge;

public DrawableBadge(Badge badge)
{
this.badge = badge;
Padding = new MarginPadding(3);
}

[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Child = new Sprite
{
FillMode = FillMode.Fit,
RelativeSizeAxes = Axes.Both,
Texture = textures.Get(badge.ImageUrl),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
OnLoadComplete = d => d.FadeInFromZero(200)

This comment was marked as off-topic.

};
}

public string TooltipText => badge.Description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System;
using System.Collections.Generic;
using System.Linq;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
Expand All @@ -14,10 +15,9 @@
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Users;
using System.Collections.Generic;
using osu.Framework.Configuration;
using OpenTK;

namespace osu.Game.Overlays.Profile
namespace osu.Game.Overlays.Profile.Header
{
public class RankGraph : Container
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using OpenTK;

namespace osu.Game.Overlays.Profile
namespace osu.Game.Overlays.Profile.Header
{
public class SupporterIcon : CircularContainer, IHasTooltip
{
Expand Down
Loading