mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 14:12:54 +08:00
Merge pull request #936 from huoyaoyuan/profile
Basic User Profile Page
This commit is contained in:
commit
406cf9d0d4
64
osu.Desktop.VisualTests/Tests/TestCaseUserProfile.cs
Normal file
64
osu.Desktop.VisualTests/Tests/TestCaseUserProfile.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Desktop.VisualTests.Tests
|
||||||
|
{
|
||||||
|
internal class TestCaseUserProfile : TestCase
|
||||||
|
{
|
||||||
|
public override string Description => "Tests user's profile page.";
|
||||||
|
|
||||||
|
public TestCaseUserProfile()
|
||||||
|
{
|
||||||
|
var profile = new UserProfileOverlay();
|
||||||
|
Add(profile);
|
||||||
|
|
||||||
|
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,
|
||||||
|
Age = 1,
|
||||||
|
ProfileOrder = new[] { "me" },
|
||||||
|
CountryRank = 1,
|
||||||
|
Statistics = new UserStatistics
|
||||||
|
{
|
||||||
|
Rank = 2148,
|
||||||
|
PP = 4567.89m
|
||||||
|
},
|
||||||
|
AllRankHistories = new User.RankHistories
|
||||||
|
{
|
||||||
|
Osu = new User.RankHistory
|
||||||
|
{
|
||||||
|
Mode = @"osu",
|
||||||
|
Data = Enumerable.Range(2345,45).Concat(Enumerable.Range(2109,40)).ToArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, false));
|
||||||
|
AddStep("Show ppy", () => profile.ShowUser(new User
|
||||||
|
{
|
||||||
|
Username = @"peppy",
|
||||||
|
Id = 2,
|
||||||
|
Country = new Country { FullName = @"Australia", FlagName = @"AU" },
|
||||||
|
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
|
||||||
|
}));
|
||||||
|
AddStep("Show flyte", () => profile.ShowUser(new User
|
||||||
|
{
|
||||||
|
Username = @"flyte",
|
||||||
|
Id = 3103765,
|
||||||
|
Country = new Country { FullName = @"Japan", FlagName = @"JP" },
|
||||||
|
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
|
||||||
|
}));
|
||||||
|
AddStep("Hide", profile.Hide);
|
||||||
|
AddStep("Show without reload", profile.Show);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -216,6 +216,7 @@
|
|||||||
<Compile Include="Tests\TestCaseTextAwesome.cs" />
|
<Compile Include="Tests\TestCaseTextAwesome.cs" />
|
||||||
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
|
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
|
||||||
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
|
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseUserProfile.cs" />
|
||||||
<Compile Include="VisualTestGame.cs" />
|
<Compile Include="VisualTestGame.cs" />
|
||||||
<Compile Include="Platform\TestStorage.cs" />
|
<Compile Include="Platform\TestStorage.cs" />
|
||||||
<Compile Include="Tests\TestCaseSettings.cs" />
|
<Compile Include="Tests\TestCaseSettings.cs" />
|
||||||
|
21
osu.Game/Graphics/Containers/OsuTextFlowContainer.cs
Normal file
21
osu.Game/Graphics/Containers/OsuTextFlowContainer.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Containers
|
||||||
|
{
|
||||||
|
public class OsuTextFlowContainer : TextFlowContainer
|
||||||
|
{
|
||||||
|
public OsuTextFlowContainer(Action<SpriteText> defaultCreationParameters = null) : base(defaultCreationParameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SpriteText CreateSpriteText() => new OsuSpriteText();
|
||||||
|
|
||||||
|
public void AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -13,11 +12,15 @@ namespace osu.Game.Graphics.Containers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container that can scroll to each section inside it.
|
/// A container that can scroll to each section inside it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SectionsContainer : Container
|
public class SectionsContainer<T> : Container<T>
|
||||||
|
where T : Drawable
|
||||||
{
|
{
|
||||||
private Drawable expandableHeader, fixedHeader, footer;
|
private Drawable expandableHeader, fixedHeader, footer, headerBackground;
|
||||||
public readonly ScrollContainer ScrollContainer;
|
private readonly ScrollContainer scrollContainer;
|
||||||
private readonly Container<Drawable> sectionsContainer;
|
private readonly Container headerBackgroundContainer;
|
||||||
|
private readonly FlowContainer<T> scrollContentContainer;
|
||||||
|
|
||||||
|
protected override Container<T> Content => scrollContentContainer;
|
||||||
|
|
||||||
public Drawable ExpandableHeader
|
public Drawable ExpandableHeader
|
||||||
{
|
{
|
||||||
@ -26,12 +29,11 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
if (value == expandableHeader) return;
|
if (value == expandableHeader) return;
|
||||||
|
|
||||||
if (expandableHeader != null)
|
expandableHeader?.Expire();
|
||||||
Remove(expandableHeader);
|
|
||||||
expandableHeader = value;
|
expandableHeader = value;
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
Add(expandableHeader);
|
AddInternal(expandableHeader);
|
||||||
lastKnownScroll = float.NaN;
|
lastKnownScroll = float.NaN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,12 +45,11 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
if (value == fixedHeader) return;
|
if (value == fixedHeader) return;
|
||||||
|
|
||||||
if (fixedHeader != null)
|
fixedHeader?.Expire();
|
||||||
Remove(fixedHeader);
|
|
||||||
fixedHeader = value;
|
fixedHeader = value;
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
Add(fixedHeader);
|
AddInternal(fixedHeader);
|
||||||
lastKnownScroll = float.NaN;
|
lastKnownScroll = float.NaN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,69 +62,84 @@ namespace osu.Game.Graphics.Containers
|
|||||||
if (value == footer) return;
|
if (value == footer) return;
|
||||||
|
|
||||||
if (footer != null)
|
if (footer != null)
|
||||||
ScrollContainer.Remove(footer);
|
scrollContainer.Remove(footer);
|
||||||
footer = value;
|
footer = value;
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
footer.Anchor |= Anchor.y2;
|
footer.Anchor |= Anchor.y2;
|
||||||
footer.Origin |= Anchor.y2;
|
footer.Origin |= Anchor.y2;
|
||||||
ScrollContainer.Add(footer);
|
scrollContainer.Add(footer);
|
||||||
lastKnownScroll = float.NaN;
|
lastKnownScroll = float.NaN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bindable<Drawable> SelectedSection { get; } = new Bindable<Drawable>();
|
public Drawable HeaderBackground
|
||||||
|
|
||||||
protected virtual Container<Drawable> CreateScrollContentContainer()
|
|
||||||
=> new FillFlowContainer
|
|
||||||
{
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
AutoSizeAxes = Axes.Both
|
|
||||||
};
|
|
||||||
|
|
||||||
private List<Drawable> sections = new List<Drawable>();
|
|
||||||
public IEnumerable<Drawable> Sections
|
|
||||||
{
|
{
|
||||||
get { return sections; }
|
get { return headerBackground; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
foreach (var section in sections)
|
if (value == headerBackground) return;
|
||||||
sectionsContainer.Remove(section);
|
|
||||||
|
|
||||||
sections = value.ToList();
|
headerBackgroundContainer.Clear();
|
||||||
if (sections.Count == 0) return;
|
headerBackground = value;
|
||||||
|
if (value == null) return;
|
||||||
|
|
||||||
|
headerBackgroundContainer.Add(headerBackground);
|
||||||
|
|
||||||
sectionsContainer.AddRange(sections);
|
|
||||||
SelectedSection.Value = sections[0];
|
|
||||||
lastKnownScroll = float.NaN;
|
lastKnownScroll = float.NaN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bindable<T> SelectedSection { get; } = new Bindable<T>();
|
||||||
|
|
||||||
|
protected virtual FlowContainer<T> CreateScrollContentContainer()
|
||||||
|
=> new FillFlowContainer<T>
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
};
|
||||||
|
|
||||||
|
public override void Add(T drawable)
|
||||||
|
{
|
||||||
|
base.Add(drawable);
|
||||||
|
lastKnownScroll = float.NaN;
|
||||||
|
headerHeight = float.NaN;
|
||||||
|
footerHeight = float.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
private float headerHeight, footerHeight;
|
private float headerHeight, footerHeight;
|
||||||
private readonly MarginPadding originalSectionsMargin;
|
private readonly MarginPadding originalSectionsMargin;
|
||||||
private void updateSectionsMargin()
|
private void updateSectionsMargin()
|
||||||
{
|
{
|
||||||
if (sections.Count == 0) return;
|
if (!Children.Any()) return;
|
||||||
|
|
||||||
var newMargin = originalSectionsMargin;
|
var newMargin = originalSectionsMargin;
|
||||||
newMargin.Top += headerHeight;
|
newMargin.Top += headerHeight;
|
||||||
newMargin.Bottom += footerHeight;
|
newMargin.Bottom += footerHeight;
|
||||||
|
|
||||||
sectionsContainer.Margin = newMargin;
|
scrollContentContainer.Margin = newMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SectionsContainer()
|
public SectionsContainer()
|
||||||
{
|
{
|
||||||
Add(ScrollContainer = new OsuScrollContainer
|
AddInternal(scrollContainer = new ScrollContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = false,
|
Masking = true,
|
||||||
Children = new Drawable[] { sectionsContainer = CreateScrollContentContainer() }
|
ScrollbarVisible = false,
|
||||||
|
Children = new Drawable[] { scrollContentContainer = CreateScrollContentContainer() },
|
||||||
|
Depth = float.MaxValue
|
||||||
});
|
});
|
||||||
originalSectionsMargin = sectionsContainer.Margin;
|
AddInternal(headerBackgroundContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Depth = float.MaxValue / 2
|
||||||
|
});
|
||||||
|
originalSectionsMargin = scrollContentContainer.Margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScrollTo(Drawable section) => ScrollContainer.ScrollTo(ScrollContainer.GetChildPosInContent(section) - FixedHeader.BoundingBox.Height);
|
public void ScrollTo(Drawable section) => scrollContainer.ScrollTo(scrollContainer.GetChildPosInContent(section) - (FixedHeader?.BoundingBox.Height ?? 0));
|
||||||
|
|
||||||
private float lastKnownScroll;
|
private float lastKnownScroll;
|
||||||
protected override void UpdateAfterChildren()
|
protected override void UpdateAfterChildren()
|
||||||
@ -139,25 +155,30 @@ namespace osu.Game.Graphics.Containers
|
|||||||
updateSectionsMargin();
|
updateSectionsMargin();
|
||||||
}
|
}
|
||||||
|
|
||||||
float currentScroll = Math.Max(0, ScrollContainer.Current);
|
float currentScroll = scrollContainer.Current;
|
||||||
|
|
||||||
if (currentScroll != lastKnownScroll)
|
if (currentScroll != lastKnownScroll)
|
||||||
{
|
{
|
||||||
lastKnownScroll = currentScroll;
|
lastKnownScroll = currentScroll;
|
||||||
|
|
||||||
if (expandableHeader != null && fixedHeader != null)
|
if (ExpandableHeader != null && FixedHeader != null)
|
||||||
{
|
{
|
||||||
float offset = Math.Min(expandableHeader.LayoutSize.Y, currentScroll);
|
float offset = Math.Min(ExpandableHeader.LayoutSize.Y, currentScroll);
|
||||||
|
|
||||||
expandableHeader.Y = -offset;
|
ExpandableHeader.Y = -offset;
|
||||||
fixedHeader.Y = -offset + expandableHeader.LayoutSize.Y;
|
FixedHeader.Y = -offset + ExpandableHeader.LayoutSize.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawable bestMatch = null;
|
headerBackgroundContainer.Height = (ExpandableHeader?.LayoutSize.Y ?? 0) + (FixedHeader?.LayoutSize.Y ?? 0);
|
||||||
float minDiff = float.MaxValue;
|
headerBackgroundContainer.Y = ExpandableHeader?.Y ?? 0;
|
||||||
|
|
||||||
foreach (var section in sections)
|
T bestMatch = null;
|
||||||
|
float minDiff = float.MaxValue;
|
||||||
|
float scrollOffset = FixedHeader?.LayoutSize.Y ?? 0;
|
||||||
|
|
||||||
|
foreach (var section in Children)
|
||||||
{
|
{
|
||||||
float diff = Math.Abs(ScrollContainer.GetChildPosInContent(section) - currentScroll);
|
float diff = Math.Abs(scrollContainer.GetChildPosInContent(section) - currentScroll - scrollOffset);
|
||||||
if (diff < minDiff)
|
if (diff < minDiff)
|
||||||
{
|
{
|
||||||
minDiff = diff;
|
minDiff = diff;
|
||||||
|
102
osu.Game/Graphics/UserInterface/LineGraph.cs
Normal file
102
osu.Game/Graphics/UserInterface/LineGraph.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright (c) 2007-2017 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 OpenTK;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Lines;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.UserInterface
|
||||||
|
{
|
||||||
|
public class LineGraph : Container
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manually set the max value, otherwise <see cref="Enumerable.Max(IEnumerable{float})"/> will be used.
|
||||||
|
/// </summary>
|
||||||
|
public float? MaxValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manually set the min value, otherwise <see cref="Enumerable.Min(IEnumerable{float})"/> will be used.
|
||||||
|
/// </summary>
|
||||||
|
public float? MinValue { get; set; }
|
||||||
|
|
||||||
|
public float ActualMaxValue { get; private set; } = float.NaN;
|
||||||
|
public float ActualMinValue { get; private set; } = float.NaN;
|
||||||
|
|
||||||
|
private const double transform_duration = 1500;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hold an empty area if values are less.
|
||||||
|
/// </summary>
|
||||||
|
public int DefaultValueCount;
|
||||||
|
|
||||||
|
private readonly Container<Path> maskingContainer;
|
||||||
|
private readonly Path path;
|
||||||
|
|
||||||
|
private float[] values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of floats decides position of each line node.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<float> Values
|
||||||
|
{
|
||||||
|
get { return values; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
values = value.ToArray();
|
||||||
|
applyPath();
|
||||||
|
maskingContainer.Width = 0;
|
||||||
|
maskingContainer.ResizeWidthTo(1, transform_duration, EasingTypes.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineGraph()
|
||||||
|
{
|
||||||
|
Add(maskingContainer = new Container<Path>
|
||||||
|
{
|
||||||
|
Masking = true,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = path = new Path { RelativeSizeAxes = Axes.Both, PathWidth = 1 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||||
|
{
|
||||||
|
if ((invalidation & Invalidation.DrawSize) != 0)
|
||||||
|
applyPath();
|
||||||
|
return base.Invalidate(invalidation, source, shallPropagate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyPath()
|
||||||
|
{
|
||||||
|
path.ClearVertices();
|
||||||
|
if (values == null) return;
|
||||||
|
|
||||||
|
int count = Math.Max(values.Length, DefaultValueCount);
|
||||||
|
|
||||||
|
float max = values.Max(), min = values.Min();
|
||||||
|
if (MaxValue > max) max = MaxValue.Value;
|
||||||
|
if (MinValue < min) min = MinValue.Value;
|
||||||
|
|
||||||
|
ActualMaxValue = max;
|
||||||
|
ActualMinValue = min;
|
||||||
|
|
||||||
|
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;
|
||||||
|
// the -1 is for inner offset in path (actually -PathWidth)
|
||||||
|
path.AddVertex(new Vector2(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float GetYPosition(float value)
|
||||||
|
{
|
||||||
|
if (ActualMaxValue == ActualMinValue) return 0;
|
||||||
|
return (ActualMaxValue - value) / (ActualMaxValue - ActualMinValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem(value);
|
protected override TabItem<T> CreateTabItem(T value) => new OsuTabItem(value);
|
||||||
|
|
||||||
private bool isEnumType => typeof(T).IsEnum;
|
private static bool isEnumType => typeof(T).IsEnum;
|
||||||
|
|
||||||
public OsuTabControl()
|
public OsuTabControl()
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -23,12 +24,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Height = 30;
|
Height = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PageTabItem : TabItem<T>
|
public class PageTabItem : TabItem<T>
|
||||||
{
|
{
|
||||||
private const float transition_duration = 100;
|
private const float transition_duration = 100;
|
||||||
|
|
||||||
private readonly Box box;
|
private readonly Box box;
|
||||||
|
|
||||||
|
protected readonly SpriteText Text;
|
||||||
|
|
||||||
public PageTabItem(T value) : base(value)
|
public PageTabItem(T value) : base(value)
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.X;
|
AutoSizeAxes = Axes.X;
|
||||||
@ -36,12 +39,12 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OsuSpriteText
|
Text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Top = 8, Bottom = 8 },
|
Margin = new MarginPadding { Top = 8, Bottom = 8 },
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Text = (value as Enum).GetDescription() ?? value.ToString(),
|
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
|
||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
Font = @"Exo2.0-Bold",
|
Font = @"Exo2.0-Bold",
|
||||||
},
|
},
|
||||||
|
@ -7,9 +7,9 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
public class GetUserRequest : APIRequest<User>
|
public class GetUserRequest : APIRequest<User>
|
||||||
{
|
{
|
||||||
private int? userId;
|
private long? userId;
|
||||||
|
|
||||||
public GetUserRequest(int? userId = null)
|
public GetUserRequest(long? userId = null)
|
||||||
{
|
{
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
private SocialOverlay social;
|
private SocialOverlay social;
|
||||||
|
|
||||||
|
private UserProfileOverlay userProfile;
|
||||||
|
|
||||||
private Intro intro
|
private Intro intro
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -173,6 +175,7 @@ namespace osu.Game
|
|||||||
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
LoadComponentAsync(chat = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
||||||
|
LoadComponentAsync(userProfile = new UserProfileOverlay { Depth = -1 }, mainContent.Add);
|
||||||
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
LoadComponentAsync(settings = new SettingsOverlay { Depth = -1 }, overlayContent.Add);
|
||||||
LoadComponentAsync(musicController = new MusicController
|
LoadComponentAsync(musicController = new MusicController
|
||||||
{
|
{
|
||||||
@ -207,6 +210,7 @@ namespace osu.Game
|
|||||||
Dependencies.Cache(settings);
|
Dependencies.Cache(settings);
|
||||||
Dependencies.Cache(social);
|
Dependencies.Cache(social);
|
||||||
Dependencies.Cache(chat);
|
Dependencies.Cache(chat);
|
||||||
|
Dependencies.Cache(userProfile);
|
||||||
Dependencies.Cache(musicController);
|
Dependencies.Cache(musicController);
|
||||||
Dependencies.Cache(notificationManager);
|
Dependencies.Cache(notificationManager);
|
||||||
Dependencies.Cache(dialogOverlay);
|
Dependencies.Cache(dialogOverlay);
|
||||||
@ -322,6 +326,7 @@ namespace osu.Game
|
|||||||
chat.State = Visibility.Hidden;
|
chat.State = Visibility.Hidden;
|
||||||
direct.State = Visibility.Hidden;
|
direct.State = Visibility.Hidden;
|
||||||
social.State = Visibility.Hidden;
|
social.State = Visibility.Hidden;
|
||||||
|
userProfile.State = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,7 @@ namespace osu.Game.Overlays
|
|||||||
settingsSection = new LoginSettings
|
settingsSection = new LoginSettings
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding(10),
|
Padding = new MarginPadding(10),
|
||||||
|
RequestHide = Hide,
|
||||||
},
|
},
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
|
@ -2,15 +2,16 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK.Graphics;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Music
|
namespace osu.Game.Overlays.Music
|
||||||
{
|
{
|
||||||
@ -77,7 +78,7 @@ namespace osu.Game.Overlays.Music
|
|||||||
Margin = new MarginPadding { Left = 5 },
|
Margin = new MarginPadding { Left = 5 },
|
||||||
Padding = new MarginPadding { Top = 2 },
|
Padding = new MarginPadding { Top = 2 },
|
||||||
},
|
},
|
||||||
text = new TextFlowContainer
|
text = new OsuTextFlowContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
|
483
osu.Game/Overlays/Profile/ProfileHeader.cs
Normal file
483
osu.Game/Overlays/Profile/ProfileHeader.cs
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
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 osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile
|
||||||
|
{
|
||||||
|
public class ProfileHeader : Container
|
||||||
|
{
|
||||||
|
private readonly OsuTextFlowContainer infoTextLeft, infoTextRight;
|
||||||
|
private readonly FillFlowContainer<SpriteText> scoreText, scoreNumberText;
|
||||||
|
|
||||||
|
private readonly Container coverContainer, chartContainer, supporterTag;
|
||||||
|
private readonly Sprite levelBadge;
|
||||||
|
private readonly SpriteText levelText;
|
||||||
|
private readonly GradeBadge gradeSSPlus, gradeSS, gradeSPlus, gradeS, gradeA;
|
||||||
|
private readonly Box colourBar;
|
||||||
|
|
||||||
|
private const float cover_height = 350;
|
||||||
|
private const float info_height = 150;
|
||||||
|
private const float info_width = 220;
|
||||||
|
private const float avatar_size = 110;
|
||||||
|
private const float level_position = 30;
|
||||||
|
private const float level_height = 60;
|
||||||
|
|
||||||
|
public ProfileHeader(User user)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = cover_height + info_height;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
coverContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = cover_height,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ColourInfo = ColourInfo.GradientVertical(Color4.Black.Opacity(0.1f), Color4.Black.Opacity(0.75f))
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
|
Y = -20,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
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 CircularContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Y = -75,
|
||||||
|
Size = new Vector2(25, 25),
|
||||||
|
Masking = true,
|
||||||
|
BorderThickness = 3,
|
||||||
|
BorderColour = Color4.White,
|
||||||
|
Alpha = 0,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
},
|
||||||
|
new TextAwesome
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_heart,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
TextSize = 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = user.Username,
|
||||||
|
TextSize = 30,
|
||||||
|
Font = @"Exo2.0-RegularItalic",
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Y = -48
|
||||||
|
},
|
||||||
|
new DrawableFlag(user.Country?.FlagName ?? "__")
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Width = 30,
|
||||||
|
Height = 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colourBar = new Box
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft,
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
|
Height = 5,
|
||||||
|
Width = info_width,
|
||||||
|
Alpha = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
infoTextLeft = new OsuTextFlowContainer(t =>
|
||||||
|
{
|
||||||
|
t.TextSize = 14;
|
||||||
|
t.Alpha = 0.8f;
|
||||||
|
})
|
||||||
|
{
|
||||||
|
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
|
Y = cover_height + 20,
|
||||||
|
Width = info_width,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
ParagraphSpacing = 0.8f,
|
||||||
|
LineSpacing = 0.2f
|
||||||
|
},
|
||||||
|
infoTextRight = new OsuTextFlowContainer(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 = 280,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Y = level_position,
|
||||||
|
Height = level_height,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black.Opacity(0.5f),
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
levelBadge = new Sprite
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Height = 50,
|
||||||
|
Width = 50,
|
||||||
|
Alpha = 0
|
||||||
|
},
|
||||||
|
levelText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Y = 11,
|
||||||
|
TextSize = 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Y = cover_height,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Height = cover_height - level_height - level_position - 5,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black.Opacity(0.5f),
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
scoreText = new FillFlowContainer<SpriteText>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Padding = new MarginPadding { Horizontal = 20, Vertical = 18 },
|
||||||
|
Spacing = new Vector2(0, 2)
|
||||||
|
},
|
||||||
|
scoreNumberText = new FillFlowContainer<SpriteText>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Padding = new MarginPadding { Horizontal = 20, Vertical = 18 },
|
||||||
|
Spacing = new Vector2(0, 2)
|
||||||
|
},
|
||||||
|
new FillFlowContainer<GradeBadge>
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Y = -64,
|
||||||
|
Spacing = new Vector2(20, 0),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
gradeSSPlus = new GradeBadge("SSPlus") { Alpha = 0 },
|
||||||
|
gradeSS = new GradeBadge("SS") { Alpha = 0 },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new FillFlowContainer<GradeBadge>
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Y = -18,
|
||||||
|
Spacing = new Vector2(20, 0),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
gradeSPlus = new GradeBadge("SPlus") { Alpha = 0 },
|
||||||
|
gradeS = new GradeBadge("S") { Alpha = 0 },
|
||||||
|
gradeA = new GradeBadge("A") { Alpha = 0 },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chartContainer = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
Height = info_height - 15,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black.Opacity(0.25f),
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
levelBadge.Texture = textures.Get(@"Profile/levelbadge");
|
||||||
|
}
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public User User
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
user = value;
|
||||||
|
loadUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadUser()
|
||||||
|
{
|
||||||
|
coverContainer.Add(new AsyncLoadWrapper(new UserCoverBackground(user)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
FillMode = FillMode.Fill,
|
||||||
|
OnLoadComplete = d => d.FadeInFromZero(200)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
Masking = true,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Depth = float.MaxValue
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user.IsSupporter) supporterTag.Show();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(user.Colour))
|
||||||
|
{
|
||||||
|
colourBar.Colour = OsuColour.FromHex(user.Colour);
|
||||||
|
colourBar.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
Action<SpriteText> boldItalic = t =>
|
||||||
|
{
|
||||||
|
t.Font = @"Exo2.0-BoldItalic";
|
||||||
|
t.Alpha = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (user.Age != null)
|
||||||
|
{
|
||||||
|
infoTextLeft.AddText($"{user.Age} years old ", boldItalic);
|
||||||
|
}
|
||||||
|
if (user.Country != null)
|
||||||
|
{
|
||||||
|
infoTextLeft.AddText("from ");
|
||||||
|
infoTextLeft.AddText(user.Country.FullName, boldItalic);
|
||||||
|
}
|
||||||
|
infoTextLeft.NewParagraph();
|
||||||
|
|
||||||
|
if (user.JoinDate.ToUniversalTime().Year < 2008)
|
||||||
|
{
|
||||||
|
infoTextLeft.AddText("Here since the beginning", boldItalic);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoTextLeft.AddText("Joined ");
|
||||||
|
infoTextLeft.AddText(user.JoinDate.LocalDateTime.ToShortDateString(), boldItalic);
|
||||||
|
}
|
||||||
|
infoTextLeft.NewLine();
|
||||||
|
infoTextLeft.AddText("Last seen ");
|
||||||
|
infoTextLeft.AddText(user.LastVisit.LocalDateTime.ToShortDateString(), boldItalic);
|
||||||
|
infoTextLeft.NewParagraph();
|
||||||
|
|
||||||
|
if (user.PlayStyle?.Length > 0)
|
||||||
|
{
|
||||||
|
infoTextLeft.AddText("Plays with ");
|
||||||
|
infoTextLeft.AddText(string.Join(", ", user.PlayStyle), boldItalic);
|
||||||
|
}
|
||||||
|
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_map_marker, user.Location);
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_heart_o, user.Intrerests);
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_suitcase, user.Occupation);
|
||||||
|
infoTextRight.NewParagraph();
|
||||||
|
if (!string.IsNullOrEmpty(user.Twitter))
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_twitter, "@" + user.Twitter);
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_globe, user.Website);
|
||||||
|
tryAddInfoRightLine(FontAwesome.fa_skype, user.Skype);
|
||||||
|
|
||||||
|
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}%"));
|
||||||
|
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("Replay Watched by Others"));
|
||||||
|
scoreNumberText.Add(createScoreNumberText(user.Statistics.ReplayWatched.ToString(@"#,0")));
|
||||||
|
|
||||||
|
gradeSS.DisplayCount = user.Statistics.GradesCount.SS;
|
||||||
|
gradeSS.Show();
|
||||||
|
gradeS.DisplayCount = user.Statistics.GradesCount.S;
|
||||||
|
gradeS.Show();
|
||||||
|
gradeA.DisplayCount = user.Statistics.GradesCount.A;
|
||||||
|
gradeA.Show();
|
||||||
|
|
||||||
|
gradeSPlus.DisplayCount = 0;
|
||||||
|
gradeSSPlus.DisplayCount = 0;
|
||||||
|
|
||||||
|
chartContainer.Add(new RankChart(user) { RelativeSizeAxes = Axes.Both });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These could be local functions when C# 7 enabled
|
||||||
|
|
||||||
|
private OsuSpriteText createScoreText(string text) => new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Text = text
|
||||||
|
};
|
||||||
|
|
||||||
|
private OsuSpriteText createScoreNumberText(string text) => new OsuSpriteText
|
||||||
|
{
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold",
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Text = text
|
||||||
|
};
|
||||||
|
|
||||||
|
private void tryAddInfoRightLine(FontAwesome icon, string str)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(str)) return;
|
||||||
|
|
||||||
|
infoTextRight.AddIcon(icon);
|
||||||
|
infoTextRight.AddText(" " + str);
|
||||||
|
infoTextRight.NewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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 SpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
TextSize = 14,
|
||||||
|
Font = @"Exo2.0-Bold"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
badge.Texture = textures.Get($"Grades/{grade}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
osu.Game/Overlays/Profile/ProfileSection.cs
Normal file
74
osu.Game/Overlays/Profile/ProfileSection.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using OpenTK;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile
|
||||||
|
{
|
||||||
|
public abstract class ProfileSection : FillFlowContainer
|
||||||
|
{
|
||||||
|
public abstract string Title { get; }
|
||||||
|
|
||||||
|
public abstract string Identifier { get; }
|
||||||
|
|
||||||
|
private readonly FillFlowContainer content;
|
||||||
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
|
protected ProfileSection()
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = Title,
|
||||||
|
TextSize = 20,
|
||||||
|
Font = @"Exo2.0-RegularItalic",
|
||||||
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
|
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
|
Vertical = 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Padding = new MarginPadding
|
||||||
|
{
|
||||||
|
Horizontal = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||||
|
Bottom = 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
Colour = OsuColour.Gray(34),
|
||||||
|
EdgeSmoothness = new Vector2(1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// placeholder
|
||||||
|
Add(new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = @"coming soon!",
|
||||||
|
TextSize = 16,
|
||||||
|
Font = @"Exo2.0-Medium",
|
||||||
|
Colour = Color4.Gray,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Margin = new MarginPadding { Top = 100, Bottom = 100 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
177
osu.Game/Overlays/Profile/RankChart.cs
Normal file
177
osu.Game/Overlays/Profile/RankChart.cs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
// Copyright (c) 2007-2017 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 OpenTK;
|
||||||
|
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;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile
|
||||||
|
{
|
||||||
|
public class RankChart : Container
|
||||||
|
{
|
||||||
|
private readonly SpriteText rankText, performanceText, relativeText;
|
||||||
|
private readonly RankChartLineGraph graph;
|
||||||
|
|
||||||
|
private readonly int[] ranks;
|
||||||
|
|
||||||
|
private const float primary_textsize = 25, secondary_textsize = 13, padding = 10;
|
||||||
|
|
||||||
|
private readonly User user;
|
||||||
|
|
||||||
|
public RankChart(User user)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
|
||||||
|
Padding = new MarginPadding { Vertical = padding };
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
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
|
||||||
|
},
|
||||||
|
graph = new RankChartLineGraph
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Y = -secondary_textsize,
|
||||||
|
DefaultValueCount = 90,
|
||||||
|
BallRelease = updateRankTexts,
|
||||||
|
BallMove = showHistoryRankTexts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ranks = user.AllRankHistories?.Osu?.Data ?? new[] { user.Statistics.Rank };
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRankTexts()
|
||||||
|
{
|
||||||
|
rankText.Text = user.Statistics.Rank > 0 ? $"#{user.Statistics.Rank:#,0}" : "no rank";
|
||||||
|
performanceText.Text = user.Statistics.PP != null ? $"{user.Statistics.PP:#,0}pp" : string.Empty;
|
||||||
|
relativeText.Text = $"{user.Country?.FullName} #{user.CountryRank:#,0}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showHistoryRankTexts(int dayIndex)
|
||||||
|
{
|
||||||
|
rankText.Text = ranks[dayIndex] > 0 ? $"#{ranks[dayIndex]:#,0}" : "no rank";
|
||||||
|
relativeText.Text = dayIndex == ranks.Length ? "Now" : $"{ranks.Length - dayIndex} days ago";
|
||||||
|
//plural should be handled in a general way
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
graph.Colour = colours.Yellow;
|
||||||
|
|
||||||
|
if (user.Statistics.Rank > 0)
|
||||||
|
{
|
||||||
|
// use logarithmic coordinates
|
||||||
|
graph.Values = ranks.Select(x => -(float)Math.Log(x));
|
||||||
|
graph.ResetBall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||||
|
{
|
||||||
|
if ((invalidation & Invalidation.DrawSize) != 0)
|
||||||
|
{
|
||||||
|
graph.Height = DrawHeight - padding * 2 - primary_textsize - secondary_textsize * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.Invalidate(invalidation, source, shallPropagate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RankChartLineGraph : LineGraph
|
||||||
|
{
|
||||||
|
private readonly CircularContainer ball;
|
||||||
|
private bool ballShown;
|
||||||
|
|
||||||
|
private const double transform_duration = 100;
|
||||||
|
|
||||||
|
public Action<int> BallMove;
|
||||||
|
public Action BallRelease;
|
||||||
|
|
||||||
|
public RankChartLineGraph()
|
||||||
|
{
|
||||||
|
Add(ball = new CircularContainer
|
||||||
|
{
|
||||||
|
Size = new Vector2(8),
|
||||||
|
Masking = true,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Alpha = 0,
|
||||||
|
RelativePositionAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box { RelativeSizeAxes = Axes.Both }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetBall()
|
||||||
|
{
|
||||||
|
ball.MoveTo(new Vector2(1, GetYPosition(Values.Last())), ballShown ? transform_duration : 0, EasingTypes.OutQuint);
|
||||||
|
ball.Show();
|
||||||
|
BallRelease();
|
||||||
|
ballShown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseMove(InputState state)
|
||||||
|
{
|
||||||
|
if (ballShown)
|
||||||
|
{
|
||||||
|
var values = (IList<float>)Values;
|
||||||
|
var position = ToLocalSpace(state.Mouse.NativeState.Position);
|
||||||
|
int count = Math.Max(values.Count, DefaultValueCount);
|
||||||
|
int index = (int)Math.Round(position.X / DrawWidth * (count - 1));
|
||||||
|
if (index >= count - values.Count)
|
||||||
|
{
|
||||||
|
int i = index + values.Count - count;
|
||||||
|
float y = GetYPosition(values[i]);
|
||||||
|
if (Math.Abs(y * DrawHeight - position.Y) <= 8f)
|
||||||
|
{
|
||||||
|
ball.MoveTo(new Vector2(index / (float)(count - 1), y), transform_duration, EasingTypes.OutQuint);
|
||||||
|
BallMove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base.OnMouseMove(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(InputState state)
|
||||||
|
{
|
||||||
|
if (ballShown)
|
||||||
|
ResetBall();
|
||||||
|
base.OnHoverLost(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/AboutSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/AboutSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class AboutSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "me!";
|
||||||
|
|
||||||
|
public override string Identifier => "me";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class BeatmapsSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Beatmaps";
|
||||||
|
|
||||||
|
public override string Identifier => "beatmaps";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/HistoricalSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/HistoricalSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class HistoricalSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Historical";
|
||||||
|
|
||||||
|
public override string Identifier => "historical";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/KudosuSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/KudosuSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class KudosuSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Kudosu!";
|
||||||
|
|
||||||
|
public override string Identifier => "kudosu";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/MedalsSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/MedalsSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class MedalsSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Medals";
|
||||||
|
|
||||||
|
public override string Identifier => "medals";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/RanksSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/RanksSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class RanksSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Ranks";
|
||||||
|
|
||||||
|
public override string Identifier => "top_ranks";
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Overlays/Profile/Sections/RecentSection.cs
Normal file
12
osu.Game/Overlays/Profile/Sections/RecentSection.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
|
{
|
||||||
|
public class RecentSection : ProfileSection
|
||||||
|
{
|
||||||
|
public override string Title => "Recent";
|
||||||
|
|
||||||
|
public override string Identifier => "recent_activities";
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -31,6 +32,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
private UserPanel panel;
|
private UserPanel panel;
|
||||||
private UserDropdown dropdown;
|
private UserDropdown dropdown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called to request a hide of a parent displaying this container.
|
||||||
|
/// </summary>
|
||||||
|
public Action RequestHide;
|
||||||
|
|
||||||
public override RectangleF BoundingBox => bounding ? base.BoundingBox : RectangleF.Empty;
|
public override RectangleF BoundingBox => bounding ? base.BoundingBox : RectangleF.Empty;
|
||||||
|
|
||||||
public bool Bounding
|
public bool Bounding
|
||||||
@ -58,6 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
{
|
{
|
||||||
this.inputManager = inputManager;
|
this.inputManager = inputManager;
|
||||||
this.colours = colours;
|
this.colours = colours;
|
||||||
|
|
||||||
api?.Register(this);
|
api?.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +136,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
panel = new UserPanel(api.LocalUser.Value) { RelativeSizeAxes = Axes.X },
|
panel = new UserPanel(api.LocalUser.Value)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Action = RequestHide
|
||||||
|
},
|
||||||
dropdown = new UserDropdown { RelativeSizeAxes = Axes.X },
|
dropdown = new UserDropdown { RelativeSizeAxes = Axes.X },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Overlays
|
|||||||
},
|
},
|
||||||
Exit = Hide,
|
Exit = Hide,
|
||||||
},
|
},
|
||||||
Sections = sections,
|
Children = sections,
|
||||||
Footer = new SettingsFooter()
|
Footer = new SettingsFooter()
|
||||||
},
|
},
|
||||||
sidebar = new Sidebar
|
sidebar = new Sidebar
|
||||||
@ -163,13 +163,12 @@ namespace osu.Game.Overlays
|
|||||||
sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
|
sectionsContainer.Padding = new MarginPadding { Top = getToolbarHeight() };
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SettingsSectionsContainer : SectionsContainer
|
private class SettingsSectionsContainer : SectionsContainer<SettingsSection>
|
||||||
{
|
{
|
||||||
public SearchContainer SearchContainer;
|
public SearchContainer<SettingsSection> SearchContainer;
|
||||||
private readonly Box headerBackground;
|
|
||||||
|
|
||||||
protected override Container<Drawable> CreateScrollContentContainer()
|
protected override FlowContainer<SettingsSection> CreateScrollContentContainer()
|
||||||
=> SearchContainer = new SearchContainer
|
=> SearchContainer = new SearchContainer<SettingsSection>
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
@ -178,12 +177,11 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
public SettingsSectionsContainer()
|
public SettingsSectionsContainer()
|
||||||
{
|
{
|
||||||
ScrollContainer.ScrollbarVisible = false;
|
HeaderBackground = new Box
|
||||||
Add(headerBackground = new Box
|
|
||||||
{
|
{
|
||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
RelativeSizeAxes = Axes.X
|
RelativeSizeAxes = Axes.Both
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
protected override void UpdateAfterChildren()
|
||||||
@ -191,9 +189,7 @@ namespace osu.Game.Overlays
|
|||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
// no null check because the usage of this class is strict
|
// no null check because the usage of this class is strict
|
||||||
headerBackground.Height = ExpandableHeader.LayoutSize.Y + FixedHeader.LayoutSize.Y;
|
HeaderBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y * 0.5f;
|
||||||
headerBackground.Y = ExpandableHeader.Y;
|
|
||||||
headerBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y * 0.5f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
224
osu.Game/Overlays/UserProfileOverlay.cs
Normal file
224
osu.Game/Overlays/UserProfileOverlay.cs
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
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.UserInterface;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
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.Sections;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays
|
||||||
|
{
|
||||||
|
public class UserProfileOverlay : WaveOverlayContainer
|
||||||
|
{
|
||||||
|
private ProfileSection lastSection;
|
||||||
|
private ProfileSection[] sections;
|
||||||
|
private GetUserRequest userReq;
|
||||||
|
private APIAccess api;
|
||||||
|
private ProfileHeader header;
|
||||||
|
private SectionsContainer<ProfileSection> sectionsContainer;
|
||||||
|
private ProfileTabControl tabs;
|
||||||
|
|
||||||
|
public const float CONTENT_X_MARGIN = 50;
|
||||||
|
|
||||||
|
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
|
protected override bool OnClick(InputState state)
|
||||||
|
{
|
||||||
|
State = Visibility.Hidden;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProfileOverlay()
|
||||||
|
{
|
||||||
|
FirstWaveColour = OsuColour.Gray(0.4f);
|
||||||
|
SecondWaveColour = OsuColour.Gray(0.3f);
|
||||||
|
ThirdWaveColour = OsuColour.Gray(0.2f);
|
||||||
|
FourthWaveColour = OsuColour.Gray(0.1f);
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
RelativePositionAxes = Axes.Both;
|
||||||
|
Width = 0.85f;
|
||||||
|
Anchor = Anchor.TopCentre;
|
||||||
|
Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Colour = Color4.Black.Opacity(0),
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Radius = 10
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(APIAccess api)
|
||||||
|
{
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopIn()
|
||||||
|
{
|
||||||
|
base.PopIn();
|
||||||
|
FadeEdgeEffectTo(0.5f, APPEAR_DURATION, EasingTypes.In);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopOut()
|
||||||
|
{
|
||||||
|
base.PopOut();
|
||||||
|
FadeEdgeEffectTo(0, DISAPPEAR_DURATION, EasingTypes.Out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowUser(User user, bool fetchOnline = true)
|
||||||
|
{
|
||||||
|
userReq?.Cancel();
|
||||||
|
Clear();
|
||||||
|
lastSection = null;
|
||||||
|
|
||||||
|
sections = new ProfileSection[]
|
||||||
|
{
|
||||||
|
new AboutSection(),
|
||||||
|
new RecentSection(),
|
||||||
|
new RanksSection(),
|
||||||
|
new MedalsSection(),
|
||||||
|
new HistoricalSection(),
|
||||||
|
new BeatmapsSection(),
|
||||||
|
new KudosuSection()
|
||||||
|
};
|
||||||
|
tabs = new ProfileTabControl
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Height = 30
|
||||||
|
};
|
||||||
|
|
||||||
|
Add(new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = OsuColour.Gray(0.2f)
|
||||||
|
});
|
||||||
|
|
||||||
|
header = new ProfileHeader(user);
|
||||||
|
|
||||||
|
Add(sectionsContainer = new SectionsContainer<ProfileSection>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
ExpandableHeader = header,
|
||||||
|
FixedHeader = tabs,
|
||||||
|
HeaderBackground = new Box
|
||||||
|
{
|
||||||
|
Colour = OsuColour.Gray(34),
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sectionsContainer.SelectedSection.ValueChanged += s =>
|
||||||
|
{
|
||||||
|
if (lastSection != s)
|
||||||
|
{
|
||||||
|
lastSection = s;
|
||||||
|
tabs.Current.Value = lastSection;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tabs.Current.ValueChanged += s =>
|
||||||
|
{
|
||||||
|
if (lastSection == null)
|
||||||
|
{
|
||||||
|
lastSection = sectionsContainer.Children.FirstOrDefault();
|
||||||
|
if (lastSection != null)
|
||||||
|
tabs.Current.Value = lastSection;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lastSection != s)
|
||||||
|
{
|
||||||
|
lastSection = s;
|
||||||
|
sectionsContainer.ScrollTo(lastSection);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fetchOnline)
|
||||||
|
{
|
||||||
|
userReq = new GetUserRequest(user.Id);
|
||||||
|
userReq.Success += userLoadComplete;
|
||||||
|
api.Queue(userReq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
userReq = null;
|
||||||
|
userLoadComplete(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void userLoadComplete(User user)
|
||||||
|
{
|
||||||
|
header.User = user;
|
||||||
|
|
||||||
|
for (int i = 0; i < user.ProfileOrder.Length; i++)
|
||||||
|
{
|
||||||
|
string id = user.ProfileOrder[i];
|
||||||
|
var sec = sections.FirstOrDefault(s => s.Identifier == id);
|
||||||
|
if (sec != null)
|
||||||
|
{
|
||||||
|
sec.Depth = -i;
|
||||||
|
sectionsContainer.Add(sec);
|
||||||
|
tabs.AddItem(sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProfileTabControl : PageTabControl<ProfileSection>
|
||||||
|
{
|
||||||
|
private readonly Box bottom;
|
||||||
|
|
||||||
|
public ProfileTabControl()
|
||||||
|
{
|
||||||
|
TabContainer.RelativeSizeAxes &= ~Axes.X;
|
||||||
|
TabContainer.AutoSizeAxes |= Axes.X;
|
||||||
|
TabContainer.Anchor |= Anchor.x1;
|
||||||
|
TabContainer.Origin |= Anchor.x1;
|
||||||
|
Add(bottom = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = 1,
|
||||||
|
Anchor = Anchor.BottomCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
EdgeSmoothness = new Vector2(1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TabItem<ProfileSection> CreateTabItem(ProfileSection value) => new ProfileTabItem(value);
|
||||||
|
|
||||||
|
protected override Dropdown<ProfileSection> CreateDropdown() => null;
|
||||||
|
|
||||||
|
private class ProfileTabItem : PageTabItem
|
||||||
|
{
|
||||||
|
public ProfileTabItem(ProfileSection value) : base(value)
|
||||||
|
{
|
||||||
|
Text.Text = value.Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
bottom.Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
@ -11,17 +12,20 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty(@"id")]
|
[JsonProperty(@"id")]
|
||||||
public long Id = 1;
|
public long Id = 1;
|
||||||
|
|
||||||
|
[JsonProperty(@"join_date")]
|
||||||
|
public DateTimeOffset JoinDate;
|
||||||
|
|
||||||
[JsonProperty(@"username")]
|
[JsonProperty(@"username")]
|
||||||
public string Username;
|
public string Username;
|
||||||
|
|
||||||
[JsonProperty(@"country_code")]
|
|
||||||
public string CountryCode;
|
|
||||||
|
|
||||||
[JsonProperty(@"country")]
|
[JsonProperty(@"country")]
|
||||||
public Country Country;
|
public Country Country;
|
||||||
|
|
||||||
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
|
[JsonProperty(@"age")]
|
||||||
|
public int? Age;
|
||||||
|
|
||||||
public int GlobalRank;
|
public int GlobalRank;
|
||||||
|
|
||||||
public int CountryRank;
|
public int CountryRank;
|
||||||
@ -51,5 +55,101 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty(@"id")]
|
[JsonProperty(@"id")]
|
||||||
public int? Id;
|
public int? Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"isAdmin")]
|
||||||
|
public bool IsAdmin;
|
||||||
|
|
||||||
|
[JsonProperty(@"isSupporter")]
|
||||||
|
public bool IsSupporter;
|
||||||
|
|
||||||
|
[JsonProperty(@"isGMT")]
|
||||||
|
public bool IsGMT;
|
||||||
|
|
||||||
|
[JsonProperty(@"isQAT")]
|
||||||
|
public bool IsQAT;
|
||||||
|
|
||||||
|
[JsonProperty(@"isBNG")]
|
||||||
|
public bool IsBNG;
|
||||||
|
|
||||||
|
[JsonProperty(@"is_active")]
|
||||||
|
public bool Active;
|
||||||
|
|
||||||
|
[JsonProperty(@"interests")]
|
||||||
|
public string Intrerests;
|
||||||
|
|
||||||
|
[JsonProperty(@"occupation")]
|
||||||
|
public string Occupation;
|
||||||
|
|
||||||
|
[JsonProperty(@"title")]
|
||||||
|
public string Title;
|
||||||
|
|
||||||
|
[JsonProperty(@"location")]
|
||||||
|
public string Location;
|
||||||
|
|
||||||
|
[JsonProperty(@"lastvisit")]
|
||||||
|
public DateTimeOffset LastVisit;
|
||||||
|
|
||||||
|
[JsonProperty(@"twitter")]
|
||||||
|
public string Twitter;
|
||||||
|
|
||||||
|
[JsonProperty(@"lastfm")]
|
||||||
|
public string Lastfm;
|
||||||
|
|
||||||
|
[JsonProperty(@"skype")]
|
||||||
|
public string Skype;
|
||||||
|
|
||||||
|
[JsonProperty(@"website")]
|
||||||
|
public string Website;
|
||||||
|
|
||||||
|
[JsonProperty(@"playstyle")]
|
||||||
|
public string[] PlayStyle;
|
||||||
|
|
||||||
|
[JsonProperty(@"playmode")]
|
||||||
|
public string PlayMode;
|
||||||
|
|
||||||
|
[JsonProperty(@"profileOrder")]
|
||||||
|
public string[] ProfileOrder;
|
||||||
|
|
||||||
|
[JsonProperty(@"kudosu")]
|
||||||
|
public KudosuCount Kudosu;
|
||||||
|
|
||||||
|
public class KudosuCount
|
||||||
|
{
|
||||||
|
[JsonProperty(@"total")]
|
||||||
|
public int Total;
|
||||||
|
|
||||||
|
[JsonProperty(@"available")]
|
||||||
|
public int Available;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"defaultStatistics")]
|
||||||
|
public UserStatistics Statistics;
|
||||||
|
|
||||||
|
public class RankHistories
|
||||||
|
{
|
||||||
|
[JsonProperty(@"osu")]
|
||||||
|
public RankHistory Osu;
|
||||||
|
|
||||||
|
[JsonProperty(@"taiko")]
|
||||||
|
public RankHistory Taiko;
|
||||||
|
|
||||||
|
[JsonProperty(@"fruits")]
|
||||||
|
public RankHistory Fruits;
|
||||||
|
|
||||||
|
[JsonProperty(@"mania")]
|
||||||
|
public RankHistory Mania;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RankHistory
|
||||||
|
{
|
||||||
|
[JsonProperty(@"mode")]
|
||||||
|
public string Mode;
|
||||||
|
|
||||||
|
[JsonProperty(@"data")]
|
||||||
|
public int[] Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"allRankHistories")]
|
||||||
|
public RankHistories AllRankHistories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
osu.Game/Users/UserCoverBackground.cs
Normal file
26
osu.Game/Users/UserCoverBackground.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) 2007-2017 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.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
|
||||||
|
namespace osu.Game.Users
|
||||||
|
{
|
||||||
|
public class UserCoverBackground : Sprite
|
||||||
|
{
|
||||||
|
private readonly User user;
|
||||||
|
|
||||||
|
public UserCoverBackground(User user)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(user.CoverUrl))
|
||||||
|
Texture = textures.Get(user.CoverUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -9,29 +10,31 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Users
|
namespace osu.Game.Users
|
||||||
{
|
{
|
||||||
public class UserPanel : Container
|
public class UserPanel : ClickableContainer
|
||||||
{
|
{
|
||||||
|
private readonly User user;
|
||||||
private const float height = 100;
|
private const float height = 100;
|
||||||
private const float content_padding = 10;
|
private const float content_padding = 10;
|
||||||
private const float status_height = 30;
|
private const float status_height = 30;
|
||||||
|
|
||||||
private OsuColour colours;
|
|
||||||
|
|
||||||
private readonly Container statusBar;
|
private readonly Container statusBar;
|
||||||
private readonly Box statusBg;
|
private readonly Box statusBg;
|
||||||
private readonly OsuSpriteText statusMessage;
|
private readonly OsuSpriteText statusMessage;
|
||||||
|
|
||||||
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
public readonly Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||||
|
|
||||||
|
public new Action Action;
|
||||||
|
|
||||||
public UserPanel(User user)
|
public UserPanel(User user)
|
||||||
{
|
{
|
||||||
|
this.user = user;
|
||||||
|
|
||||||
Height = height - status_height;
|
Height = height - status_height;
|
||||||
Masking = true;
|
Masking = true;
|
||||||
CornerRadius = 5;
|
CornerRadius = 5;
|
||||||
@ -44,7 +47,7 @@ namespace osu.Game.Users
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new AsyncLoadWrapper(new CoverBackgroundSprite(user)
|
new AsyncLoadWrapper(new UserCoverBackground(user)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -162,11 +165,17 @@ namespace osu.Game.Users
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader(permitNulls: true)]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours, UserProfileOverlay profile)
|
||||||
{
|
{
|
||||||
this.colours = colours;
|
|
||||||
Status.ValueChanged += displayStatus;
|
Status.ValueChanged += displayStatus;
|
||||||
|
Status.ValueChanged += status => statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, EasingTypes.OutQuint);
|
||||||
|
|
||||||
|
base.Action = () =>
|
||||||
|
{
|
||||||
|
Action?.Invoke();
|
||||||
|
profile?.ShowUser(user);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -191,26 +200,8 @@ namespace osu.Game.Users
|
|||||||
statusBar.FadeIn(transition_duration, EasingTypes.OutQuint);
|
statusBar.FadeIn(transition_duration, EasingTypes.OutQuint);
|
||||||
ResizeHeightTo(height, transition_duration, EasingTypes.OutQuint);
|
ResizeHeightTo(height, transition_duration, EasingTypes.OutQuint);
|
||||||
|
|
||||||
statusBg.FadeColour(status.GetAppropriateColour(colours), 500, EasingTypes.OutQuint);
|
|
||||||
statusMessage.Text = status.Message;
|
statusMessage.Text = status.Message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CoverBackgroundSprite : Sprite
|
|
||||||
{
|
|
||||||
private readonly User user;
|
|
||||||
|
|
||||||
public CoverBackgroundSprite(User user)
|
|
||||||
{
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(TextureStore textures)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(user.CoverUrl))
|
|
||||||
Texture = textures.Get(user.CoverUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
64
osu.Game/Users/UserStatistics.cs
Normal file
64
osu.Game/Users/UserStatistics.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace osu.Game.Users
|
||||||
|
{
|
||||||
|
public class UserStatistics
|
||||||
|
{
|
||||||
|
[JsonProperty(@"level")]
|
||||||
|
public LevelInfo Level;
|
||||||
|
|
||||||
|
public struct LevelInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(@"current")]
|
||||||
|
public int Current;
|
||||||
|
|
||||||
|
[JsonProperty(@"progress")]
|
||||||
|
public int Progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(@"pp")]
|
||||||
|
public decimal? PP;
|
||||||
|
|
||||||
|
[JsonProperty(@"pp_rank")]
|
||||||
|
public int Rank;
|
||||||
|
|
||||||
|
[JsonProperty(@"ranked_score")]
|
||||||
|
public long RankedScore;
|
||||||
|
|
||||||
|
[JsonProperty(@"hit_accuracy")]
|
||||||
|
public decimal Accuracy;
|
||||||
|
|
||||||
|
[JsonProperty(@"play_count")]
|
||||||
|
public int PlayCount;
|
||||||
|
|
||||||
|
[JsonProperty(@"total_score")]
|
||||||
|
public long TotalScore;
|
||||||
|
|
||||||
|
[JsonProperty(@"total_hits")]
|
||||||
|
public int TotalHits;
|
||||||
|
|
||||||
|
[JsonProperty(@"maximum_combo")]
|
||||||
|
public int MaxCombo;
|
||||||
|
|
||||||
|
[JsonProperty(@"replays_watched_by_others")]
|
||||||
|
public int ReplayWatched;
|
||||||
|
|
||||||
|
[JsonProperty(@"grade_counts")]
|
||||||
|
public Grades GradesCount;
|
||||||
|
|
||||||
|
public struct Grades
|
||||||
|
{
|
||||||
|
[JsonProperty(@"ss")]
|
||||||
|
public int SS;
|
||||||
|
|
||||||
|
[JsonProperty(@"s")]
|
||||||
|
public int S;
|
||||||
|
|
||||||
|
[JsonProperty(@"a")]
|
||||||
|
public int A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -80,8 +80,10 @@
|
|||||||
<Compile Include="Graphics\Containers\OsuFocusedOverlayContainer.cs" />
|
<Compile Include="Graphics\Containers\OsuFocusedOverlayContainer.cs" />
|
||||||
<Compile Include="Graphics\Containers\OsuScrollContainer.cs" />
|
<Compile Include="Graphics\Containers\OsuScrollContainer.cs" />
|
||||||
<Compile Include="Graphics\Cursor\OsuContextMenuContainer.cs" />
|
<Compile Include="Graphics\Cursor\OsuContextMenuContainer.cs" />
|
||||||
|
<Compile Include="Graphics\Containers\OsuTextFlowContainer.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\IconButton.cs" />
|
<Compile Include="Graphics\UserInterface\IconButton.cs" />
|
||||||
<Compile Include="Configuration\SelectionRandomType.cs" />
|
<Compile Include="Configuration\SelectionRandomType.cs" />
|
||||||
|
<Compile Include="Graphics\UserInterface\LineGraph.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\MenuItemType.cs" />
|
<Compile Include="Graphics\UserInterface\MenuItemType.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\OsuContextMenu.cs" />
|
<Compile Include="Graphics\UserInterface\OsuContextMenu.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
|
<Compile Include="Graphics\UserInterface\OsuContextMenuItem.cs" />
|
||||||
@ -98,6 +100,18 @@
|
|||||||
<Compile Include="Overlays\Settings\SettingsHeader.cs" />
|
<Compile Include="Overlays\Settings\SettingsHeader.cs" />
|
||||||
<Compile Include="Overlays\Settings\Sections\Audio\MainMenuSettings.cs" />
|
<Compile Include="Overlays\Settings\Sections\Audio\MainMenuSettings.cs" />
|
||||||
<Compile Include="Overlays\Toolbar\ToolbarChatButton.cs" />
|
<Compile Include="Overlays\Toolbar\ToolbarChatButton.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\AboutSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\BeatmapsSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\HistoricalSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\KudosuSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\MedalsSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\RankChart.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\RanksSection.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\Sections\RecentSection.cs" />
|
||||||
|
<Compile Include="Users\UserCoverBackground.cs" />
|
||||||
|
<Compile Include="Overlays\UserProfileOverlay.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\ProfileHeader.cs" />
|
||||||
|
<Compile Include="Overlays\Profile\ProfileSection.cs" />
|
||||||
<Compile Include="Overlays\Toolbar\ToolbarSocialButton.cs" />
|
<Compile Include="Overlays\Toolbar\ToolbarSocialButton.cs" />
|
||||||
<Compile Include="Rulesets\Beatmaps\BeatmapConverter.cs" />
|
<Compile Include="Rulesets\Beatmaps\BeatmapConverter.cs" />
|
||||||
<Compile Include="Rulesets\Beatmaps\BeatmapProcessor.cs" />
|
<Compile Include="Rulesets\Beatmaps\BeatmapProcessor.cs" />
|
||||||
@ -466,6 +480,7 @@
|
|||||||
<Compile Include="Online\Multiplayer\Room.cs" />
|
<Compile Include="Online\Multiplayer\Room.cs" />
|
||||||
<Compile Include="Online\Multiplayer\RoomStatus.cs" />
|
<Compile Include="Online\Multiplayer\RoomStatus.cs" />
|
||||||
<Compile Include="Users\UserPanel.cs" />
|
<Compile Include="Users\UserPanel.cs" />
|
||||||
|
<Compile Include="Users\UserStatistics.cs" />
|
||||||
<Compile Include="Users\UserStatus.cs" />
|
<Compile Include="Users\UserStatus.cs" />
|
||||||
<Compile Include="Overlays\DirectOverlay.cs" />
|
<Compile Include="Overlays\DirectOverlay.cs" />
|
||||||
<Compile Include="Overlays\Direct\FilterControl.cs" />
|
<Compile Include="Overlays\Direct\FilterControl.cs" />
|
||||||
@ -516,11 +531,6 @@
|
|||||||
</None>
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup />
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
@ -192,6 +192,11 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RNG/@EntryIndexedValue">RNG</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RNG/@EntryIndexedValue">RNG</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SRGB/@EntryIndexedValue">SRGB</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SRGB/@EntryIndexedValue">SRGB</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TK/@EntryIndexedValue">TK</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TK/@EntryIndexedValue">TK</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SS/@EntryIndexedValue">SS</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PP/@EntryIndexedValue">PP</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GMT/@EntryIndexedValue">GMT</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QAT/@EntryIndexedValue">QAT</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BNG/@EntryIndexedValue">BNG</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">HINT</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">HINT</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||||
|
Loading…
Reference in New Issue
Block a user