mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 10:03:05 +08:00
Update ProfileHeader to the new design
This commit is contained in:
parent
15ae0cd70a
commit
2fe80d5568
@ -1,62 +0,0 @@
|
||||
// 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 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<Type> 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()));
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,6 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(UserProfileOverlay),
|
||||
typeof(RankGraph),
|
||||
typeof(LineGraph),
|
||||
typeof(BadgeContainer),
|
||||
typeof(SectionsContainer<>),
|
||||
typeof(SupporterIcon)
|
||||
};
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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<Path>
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
// 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.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}";
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// 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.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}");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
// 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.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;
|
||||
}
|
||||
}
|
||||
}
|
149
osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs
Normal file
149
osu.Game/Overlays/Profile/Header/ProfileHeaderTabControl.cs
Normal file
@ -0,0 +1,149 @@
|
||||
// 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.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<string>
|
||||
{
|
||||
private readonly Box bar;
|
||||
|
||||
private Color4 accentColour;
|
||||
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get => accentColour;
|
||||
set
|
||||
{
|
||||
if (accentColour == value) return;
|
||||
|
||||
accentColour = value;
|
||||
|
||||
bar.Colour = value;
|
||||
|
||||
foreach (TabItem<string> 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<string> CreateDropdown() => null;
|
||||
|
||||
protected override TabItem<string> CreateTabItem(string value) => new ProfileHeaderTabItem(value)
|
||||
{
|
||||
AccentColour = AccentColour
|
||||
};
|
||||
|
||||
private class ProfileHeaderTabItem : TabItem<string>
|
||||
{
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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<int, int>[] ranks;
|
||||
private int dayIndex;
|
||||
public Bindable<User> User = new Bindable<User>();
|
||||
|
||||
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<int> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ScoreRank, ScoreRankInfo> scoreRankInfos = new Dictionary<ScoreRank, ScoreRankInfo>();
|
||||
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,
|
||||
@ -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<string>
|
||||
{
|
||||
private readonly Box bar;
|
||||
|
||||
private Color4 accentColour;
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get => accentColour;
|
||||
set
|
||||
{
|
||||
if (accentColour == value) return;
|
||||
|
||||
accentColour = value;
|
||||
|
||||
bar.Colour = value;
|
||||
|
||||
foreach (TabItem<string> 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<string> CreateDropdown() => null;
|
||||
|
||||
protected override TabItem<string> CreateTabItem(string value) => new CoverInfoTabItem(value)
|
||||
{
|
||||
AccentColour = AccentColour
|
||||
};
|
||||
|
||||
private class CoverInfoTabItem : TabItem<string>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user