1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Add expanded/compact display modes for GameplayLeaderboard

This commit is contained in:
Dean Herbert 2021-02-19 16:46:30 +09:00
parent 43c35c5118
commit 691cfa5bc3
2 changed files with 210 additions and 139 deletions

View File

@ -50,8 +50,6 @@ namespace osu.Game.Screens.Play.HUD
{
var drawable = new GameplayLeaderboardScore(user, isTracked)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Expanded = { BindTarget = Expanded },
};

View File

@ -20,16 +20,31 @@ namespace osu.Game.Screens.Play.HUD
{
public class GameplayLeaderboardScore : CompositeDrawable, ILeaderboardScore
{
public const float EXTENDED_WIDTH = 255f;
public const float EXTENDED_WIDTH = regular_width + top_player_left_width_extension;
private const float regular_width = 235f;
// a bit hand-wavy, but there's a lot of hard-coded paddings in each of the grid's internals.
private const float compact_width = 77.5f;
private const float top_player_left_width_extension = 20f;
public const float PANEL_HEIGHT = 35f;
public const float SHEAR_WIDTH = PANEL_HEIGHT * panel_shear;
private const float panel_shear = 0.15f;
private const float rank_text_width = 35f;
private const float score_components_width = 85f;
private const float avatar_size = 25f;
private const double panel_transition_duration = 500;
private const double text_transition_duration = 200;
public Bindable<bool> Expanded = new Bindable<bool>();
private OsuSpriteText positionText, scoreText, accuracyText, comboText, usernameText;
@ -65,8 +80,15 @@ namespace osu.Game.Screens.Play.HUD
private readonly bool trackedPlayer;
private Container mainFillContainer;
private Box centralFill;
private Container backgroundPaddingAdjustContainer;
private GridContainer gridContainer;
private Container scoreComponents;
/// <summary>
/// Creates a new <see cref="GameplayLeaderboardScore"/>.
/// </summary>
@ -77,7 +99,8 @@ namespace osu.Game.Screens.Play.HUD
User = user;
this.trackedPlayer = trackedPlayer;
Size = new Vector2(EXTENDED_WIDTH, PANEL_HEIGHT);
AutoSizeAxes = Axes.X;
Height = PANEL_HEIGHT;
}
[BackgroundDependencyLoader]
@ -87,147 +110,167 @@ namespace osu.Game.Screens.Play.HUD
InternalChildren = new Drawable[]
{
mainFillContainer = new Container
new Container
{
Width = regular_width,
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Masking = true,
CornerRadius = 5f,
Shear = new Vector2(panel_shear, 0f),
Child = new Box
Margin = new MarginPadding { Left = top_player_left_width_extension },
Children = new Drawable[]
{
Alpha = 0.5f,
RelativeSizeAxes = Axes.Both,
}
},
new GridContainer
{
Width = regular_width,
RelativeSizeAxes = Axes.Y,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.Absolute, 35f),
new Dimension(),
new Dimension(GridSizeMode.Absolute, 85f),
},
Content = new[]
{
new Drawable[]
backgroundPaddingAdjustContainer = new Container
{
positionText = new OsuSpriteText
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
Padding = new MarginPadding { Right = SHEAR_WIDTH / 2 },
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.White,
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.Bold),
Shadow = false,
},
new Container
{
Padding = new MarginPadding { Horizontal = SHEAR_WIDTH / 3 },
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
mainFillContainer = new Container
{
new Container
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 5f,
Shear = new Vector2(panel_shear, 0f),
Children = new Drawable[]
{
Masking = true,
CornerRadius = 5f,
Shear = new Vector2(panel_shear, 0f),
RelativeSizeAxes = Axes.Both,
Children = new[]
new Box
{
centralFill = new Box
{
Alpha = 0.5f,
RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("3399cc"),
},
}
},
new FillFlowContainer
{
Padding = new MarginPadding { Left = SHEAR_WIDTH },
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4f, 0f),
Children = new Drawable[]
{
avatarContainer = new CircularContainer
{
Masking = true,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(25f),
Children = new Drawable[]
{
new Box
{
Name = "Placeholder while avatar loads",
Alpha = 0.3f,
RelativeSizeAxes = Axes.Both,
Colour = colours.Gray4,
}
}
},
usernameText = new OsuSpriteText
{
RelativeSizeAxes = Axes.X,
Width = 0.6f,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = Color4.White,
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold),
Text = User?.Username,
Truncate = true,
Shadow = false,
}
}
},
}
},
new Container
{
Padding = new MarginPadding { Top = 2f, Right = 17.5f, Bottom = 5f },
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = Color4.White,
Children = new Drawable[]
{
scoreText = new OsuSpriteText
{
Spacing = new Vector2(-1f, 0f),
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold, fixedWidth: true),
Shadow = false,
},
accuracyText = new OsuSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold, fixedWidth: true),
Spacing = new Vector2(-1f, 0f),
Shadow = false,
},
comboText = new OsuSpriteText
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Spacing = new Vector2(-1f, 0f),
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold, fixedWidth: true),
Shadow = false,
Alpha = 0.5f,
RelativeSizeAxes = Axes.Both,
},
},
},
}
},
gridContainer = new GridContainer
{
RelativeSizeAxes = Axes.Y,
Width = compact_width, // will be updated by expanded state.
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
ColumnDimensions = new[]
{
new Dimension(GridSizeMode.Absolute, rank_text_width),
new Dimension(),
new Dimension(GridSizeMode.AutoSize, maxSize: score_components_width),
},
Content = new[]
{
new Drawable[]
{
positionText = new OsuSpriteText
{
Padding = new MarginPadding { Right = SHEAR_WIDTH / 2 },
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.White,
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.Bold),
Shadow = false,
},
new Container
{
Padding = new MarginPadding { Horizontal = SHEAR_WIDTH / 3 },
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Container
{
Masking = true,
CornerRadius = 5f,
Shear = new Vector2(panel_shear, 0f),
RelativeSizeAxes = Axes.Both,
Children = new[]
{
centralFill = new Box
{
Alpha = 0.5f,
RelativeSizeAxes = Axes.Both,
Colour = Color4Extensions.FromHex("3399cc"),
},
}
},
new FillFlowContainer
{
Padding = new MarginPadding { Left = SHEAR_WIDTH },
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(4f, 0f),
Children = new Drawable[]
{
avatarContainer = new CircularContainer
{
Masking = true,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Size = new Vector2(avatar_size),
Children = new Drawable[]
{
new Box
{
Name = "Placeholder while avatar loads",
Alpha = 0.3f,
RelativeSizeAxes = Axes.Both,
Colour = colours.Gray4,
}
}
},
usernameText = new OsuSpriteText
{
RelativeSizeAxes = Axes.X,
Width = 0.6f,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = Color4.White,
Font = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold),
Text = User?.Username,
Truncate = true,
Shadow = false,
}
}
},
}
},
scoreComponents = new Container
{
Padding = new MarginPadding { Top = 2f, Right = 17.5f, Bottom = 5f },
AlwaysPresent = true, // required to smoothly animate autosize after hidden early.
Masking = true,
RelativeSizeAxes = Axes.Y,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Colour = Color4.White,
Children = new Drawable[]
{
scoreText = new OsuSpriteText
{
Spacing = new Vector2(-1f, 0f),
Font = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold, fixedWidth: true),
Shadow = false,
},
accuracyText = new OsuSpriteText
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold, fixedWidth: true),
Spacing = new Vector2(-1f, 0f),
Shadow = false,
},
comboText = new OsuSpriteText
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Spacing = new Vector2(-1f, 0f),
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold, fixedWidth: true),
Shadow = false,
},
},
}
}
}
}
}
}
},
};
LoadComponentAsync(new DrawableAvatar(User), avatarContainer.Add);
@ -243,18 +286,43 @@ namespace osu.Game.Screens.Play.HUD
base.LoadComplete();
updateState();
Expanded.BindValueChanged(changeExpandedState, true);
FinishTransforms(true);
}
private const double panel_transition_duration = 500;
private void changeExpandedState(ValueChangedEvent<bool> expanded)
{
scoreComponents.ClearTransforms();
if (expanded.NewValue)
{
gridContainer.ResizeWidthTo(regular_width, panel_transition_duration, Easing.OutQuint);
scoreComponents.ResizeWidthTo(score_components_width, panel_transition_duration, Easing.OutQuint);
scoreComponents.FadeIn(panel_transition_duration, Easing.OutQuint);
usernameText.FadeIn(panel_transition_duration, Easing.OutQuint);
}
else
{
gridContainer.ResizeWidthTo(compact_width, panel_transition_duration, Easing.OutQuint);
scoreComponents.ResizeWidthTo(0, panel_transition_duration, Easing.OutQuint);
scoreComponents.FadeOut(text_transition_duration, Easing.OutQuint);
usernameText.FadeOut(text_transition_duration, Easing.OutQuint);
}
}
private void updateState()
{
bool widthExtension = false;
if (HasQuit.Value)
{
// we will probably want to display this in a better way once we have a design.
// and also show states other than quit.
mainFillContainer.ResizeWidthTo(regular_width, panel_transition_duration, Easing.OutElastic);
panelColour = Color4.Gray;
textColour = Color4.White;
return;
@ -262,22 +330,29 @@ namespace osu.Game.Screens.Play.HUD
if (scorePosition == 1)
{
mainFillContainer.ResizeWidthTo(EXTENDED_WIDTH, panel_transition_duration, Easing.OutElastic);
widthExtension = true;
panelColour = Color4Extensions.FromHex("7fcc33");
textColour = Color4.White;
}
else if (trackedPlayer)
{
mainFillContainer.ResizeWidthTo(EXTENDED_WIDTH, panel_transition_duration, Easing.OutElastic);
widthExtension = true;
panelColour = Color4Extensions.FromHex("ffd966");
textColour = Color4Extensions.FromHex("2e576b");
}
else
{
mainFillContainer.ResizeWidthTo(regular_width, panel_transition_duration, Easing.OutElastic);
panelColour = Color4Extensions.FromHex("3399cc");
textColour = Color4.White;
}
this.TransformTo(nameof(SizeContainerLeftPadding), widthExtension ? -top_player_left_width_extension : 0, panel_transition_duration, Easing.OutElastic);
}
public float SizeContainerLeftPadding
{
get => backgroundPaddingAdjustContainer.Padding.Left;
set => backgroundPaddingAdjustContainer.Padding = new MarginPadding { Left = value };
}
private Color4 panelColour
@ -289,8 +364,6 @@ namespace osu.Game.Screens.Play.HUD
}
}
private const double text_transition_duration = 200;
private Color4 textColour
{
set