1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-07 07:27:25 +08:00
osu-lazer/osu.Game/Overlays/Profile/Header/BadgeContainer.cs

200 lines
6.8 KiB
C#
Raw Normal View History

2018-04-16 05:44:59 +08:00
// 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;
2018-08-27 16:26:44 +08:00
using System.Threading.Tasks;
2018-04-16 05:44:59 +08:00
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;
2018-07-21 10:38:28 +08:00
using osu.Framework.Input.States;
2018-04-16 05:44:59 +08:00
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 static readonly Vector2 badge_size = new Vector2(86, 40);
private static readonly MarginPadding outer_padding = new MarginPadding(3);
2018-04-16 05:44:59 +08:00
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,
2018-04-16 05:44:59 +08:00
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);
2018-04-16 05:44:59 +08:00
}
private int visibleBadge;
private int badgeCount;
public void ShowBadges(Badge[] badges)
{
if (badges == null || badges.Length == 0)
2018-04-16 05:44:59 +08:00
{
Hide();
return;
2018-04-16 05:44:59 +08:00
}
badgeCount = badges.Length;
badgeCountText.FadeTo(badgeCount > 1 ? 1 : 0);
badgeCountText.Text = $"{badges.Length} badges";
Show();
2018-04-16 05:44:59 +08:00
visibleBadge = 0;
badgeFlowContainer.Clear();
2018-06-08 20:20:15 +08:00
for (var index = 0; index < badges.Length; index++)
2018-04-16 05:44:59 +08:00
{
2018-06-08 20:20:15 +08:00
int displayIndex = index;
LoadComponentAsync(new DrawableBadge(badges[index])
2018-04-16 05:44:59 +08:00
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
2018-05-22 19:05:15 +08:00
}, asyncBadge =>
{
badgeFlowContainer.Add(asyncBadge);
2018-06-08 20:20:15 +08:00
// load in stable order regardless of async load order.
badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex);
2018-05-22 19:05:15 +08:00
});
2018-04-16 05:44:59 +08:00
}
}
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;
2018-04-16 05:44:59 +08:00
badgeFlowContainer.Direction = FillDirection.Horizontal;
outerBadgeContainer.AutoSizeAxes = Axes.Y;
outerBadgeContainer.Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal;
2018-04-16 05:44:59 +08:00
}
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
{
public static readonly Vector2 DRAWABLE_BADGE_SIZE = badge_size + outer_padding.Total;
2018-04-16 05:44:59 +08:00
private readonly Badge badge;
public DrawableBadge(Badge badge)
{
this.badge = badge;
Padding = outer_padding;
Size = DRAWABLE_BADGE_SIZE;
2018-04-16 05:44:59 +08:00
}
[BackgroundDependencyLoader]
2018-08-27 16:26:44 +08:00
private async Task load(TextureStore textures)
2018-04-16 05:44:59 +08:00
{
Child = new Sprite
{
FillMode = FillMode.Fit,
RelativeSizeAxes = Axes.Both,
2018-08-27 16:26:44 +08:00
Texture = await textures.GetAsync(badge.ImageUrl),
2018-04-16 05:44:59 +08:00
};
}
2018-04-18 10:42:55 +08:00
protected override void LoadComplete()
{
base.LoadComplete();
Child.FadeInFromZero(200);
}
2018-04-16 05:44:59 +08:00
public string TooltipText => badge.Description;
}
}
}