General cleanups

This commit is contained in:
smoogipoo 2020-06-19 21:41:48 +09:00
parent 81ad257a17
commit 25abdc2903
9 changed files with 98 additions and 48 deletions

View File

@ -7,6 +7,9 @@ using osuTK;
namespace osu.Game.Rulesets.Scoring namespace osu.Game.Rulesets.Scoring
{ {
/// <summary>
/// A <see cref="HitEvent"/> generated by the <see cref="ScoreProcessor"/> containing extra statistics around a <see cref="HitResult"/>.
/// </summary>
public readonly struct HitEvent public readonly struct HitEvent
{ {
/// <summary> /// <summary>
@ -31,11 +34,19 @@ namespace osu.Game.Rulesets.Scoring
public readonly HitObject LastHitObject; public readonly HitObject LastHitObject;
/// <summary> /// <summary>
/// The player's position offset, if available, at the time of the event. /// A position offset, if available, at the time of the event.
/// </summary> /// </summary>
[CanBeNull] [CanBeNull]
public readonly Vector2? PositionOffset; public readonly Vector2? PositionOffset;
/// <summary>
/// Creates a new <see cref="HitEvent"/>.
/// </summary>
/// <param name="timeOffset">The time offset from the end of <paramref name="hitObject"/> at which the event occurs.</param>
/// <param name="result">The <see cref="HitResult"/>.</param>
/// <param name="hitObject">The <see cref="HitObject"/> that triggered the event.</param>
/// <param name="lastHitObject">The previous <see cref="HitObject"/>.</param>
/// <param name="positionOffset">A positional offset.</param>
public HitEvent(double timeOffset, HitResult result, HitObject hitObject, [CanBeNull] HitObject lastHitObject, [CanBeNull] Vector2? positionOffset) public HitEvent(double timeOffset, HitResult result, HitObject hitObject, [CanBeNull] HitObject lastHitObject, [CanBeNull] Vector2? positionOffset)
{ {
TimeOffset = timeOffset; TimeOffset = timeOffset;
@ -45,6 +56,11 @@ namespace osu.Game.Rulesets.Scoring
PositionOffset = positionOffset; PositionOffset = positionOffset;
} }
/// <summary>
/// Creates a new <see cref="HitEvent"/> with an optional positional offset.
/// </summary>
/// <param name="positionOffset">The positional offset.</param>
/// <returns>The new <see cref="HitEvent"/>.</returns>
public HitEvent With(Vector2? positionOffset) => new HitEvent(TimeOffset, Result, HitObject, LastHitObject, positionOffset); public HitEvent With(Vector2? positionOffset) => new HitEvent(TimeOffset, Result, HitObject, LastHitObject, positionOffset);
} }
} }

View File

@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Scoring
/// Retrieves the <see cref="HitResult"/> with the largest hit window that produces a successful hit. /// Retrieves the <see cref="HitResult"/> with the largest hit window that produces a successful hit.
/// </summary> /// </summary>
/// <returns>The lowest allowed successful <see cref="HitResult"/>.</returns> /// <returns>The lowest allowed successful <see cref="HitResult"/>.</returns>
public HitResult LowestSuccessfulHitResult() protected HitResult LowestSuccessfulHitResult()
{ {
for (var result = HitResult.Meh; result <= HitResult.Perfect; ++result) for (var result = HitResult.Meh; result <= HitResult.Perfect; ++result)
{ {

View File

@ -136,12 +136,6 @@ namespace osu.Game.Rulesets.Scoring
lastHitObject = result.HitObject; lastHitObject = result.HitObject;
updateScore(); updateScore();
OnResultApplied(result);
}
protected virtual void OnResultApplied(JudgementResult result)
{
} }
protected virtual HitEvent CreateHitEvent(JudgementResult result) protected virtual HitEvent CreateHitEvent(JudgementResult result)
@ -174,12 +168,6 @@ namespace osu.Game.Rulesets.Scoring
hitEvents.RemoveAt(hitEvents.Count - 1); hitEvents.RemoveAt(hitEvents.Count - 1);
updateScore(); updateScore();
OnResultReverted(result);
}
protected virtual void OnResultReverted(JudgementResult result)
{
} }
private void updateScore() private void updateScore()

View File

@ -76,12 +76,11 @@ namespace osu.Game.Screens.Ranking
private static readonly Color4 contracted_middle_layer_colour = Color4Extensions.FromHex("#353535"); private static readonly Color4 contracted_middle_layer_colour = Color4Extensions.FromHex("#353535");
public event Action<PanelState> StateChanged; public event Action<PanelState> StateChanged;
public Action PostExpandAction;
/// <summary> /// <summary>
/// Whether this <see cref="ScorePanel"/> can enter into an <see cref="PanelState.Expanded"/> state. /// An action to be invoked if this <see cref="ScorePanel"/> is clicked while in an expanded state.
/// </summary> /// </summary>
public bool CanExpand = true; public Action PostExpandAction;
public readonly ScoreInfo Score; public readonly ScoreInfo Score;
@ -250,6 +249,7 @@ namespace osu.Game.Screens.Ranking
{ {
base.Size = value; base.Size = value;
// Auto-size isn't used to avoid 1-frame issues and because the score panel is removed/re-added to the container.
if (trackingContainer != null) if (trackingContainer != null)
trackingContainer.Size = value; trackingContainer.Size = value;
} }
@ -259,8 +259,7 @@ namespace osu.Game.Screens.Ranking
{ {
if (State == PanelState.Contracted) if (State == PanelState.Contracted)
{ {
if (CanExpand) State = PanelState.Expanded;
State = PanelState.Expanded;
return true; return true;
} }
@ -276,6 +275,15 @@ namespace osu.Game.Screens.Ranking
private ScorePanelTrackingContainer trackingContainer; private ScorePanelTrackingContainer trackingContainer;
/// <summary>
/// Creates a <see cref="ScorePanelTrackingContainer"/> which this <see cref="ScorePanel"/> can reside inside.
/// The <see cref="ScorePanelTrackingContainer"/> will track the size of this <see cref="ScorePanel"/>.
/// </summary>
/// <remarks>
/// This <see cref="ScorePanel"/> is immediately added as a child of the <see cref="ScorePanelTrackingContainer"/>.
/// </remarks>
/// <returns>The <see cref="ScorePanelTrackingContainer"/>.</returns>
/// <exception cref="InvalidOperationException">If a <see cref="ScorePanelTrackingContainer"/> already exists.</exception>
public ScorePanelTrackingContainer CreateTrackingContainer() public ScorePanelTrackingContainer CreateTrackingContainer()
{ {
if (trackingContainer != null) if (trackingContainer != null)

View File

@ -26,12 +26,13 @@ namespace osu.Game.Screens.Ranking
/// </summary> /// </summary>
private const float expanded_panel_spacing = 15; private const float expanded_panel_spacing = 15;
/// <summary>
/// An action to be invoked if a <see cref="ScorePanel"/> is clicked while in an expanded state.
/// </summary>
public Action PostExpandAction; public Action PostExpandAction;
public readonly Bindable<ScoreInfo> SelectedScore = new Bindable<ScoreInfo>(); public readonly Bindable<ScoreInfo> SelectedScore = new Bindable<ScoreInfo>();
public float CurrentScrollPosition => scroll.Current;
private readonly Flow flow; private readonly Flow flow;
private readonly Scroll scroll; private readonly Scroll scroll;
private ScorePanel expandedPanel; private ScorePanel expandedPanel;
@ -47,16 +48,13 @@ namespace osu.Game.Screens.Ranking
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
HandleScroll = () => expandedPanel?.IsHovered != true, // handle horizontal scroll only when not hovering the expanded panel. HandleScroll = () => expandedPanel?.IsHovered != true, // handle horizontal scroll only when not hovering the expanded panel.
Children = new Drawable[] Child = flow = new Flow
{ {
flow = new Flow Anchor = Anchor.Centre,
{ Origin = Anchor.Centre,
Anchor = Anchor.Centre, Direction = FillDirection.Horizontal,
Origin = Anchor.Centre, Spacing = new Vector2(panel_spacing, 0),
Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both,
Spacing = new Vector2(panel_spacing, 0),
AutoSizeAxes = Axes.Both,
},
} }
}; };
} }
@ -166,6 +164,10 @@ namespace osu.Game.Screens.Ranking
private bool handleInput = true; private bool handleInput = true;
/// <summary>
/// Whether this <see cref="ScorePanelList"/> or any of the <see cref="ScorePanel"/>s contained should handle scroll or click input.
/// Setting to <c>false</c> will also hide the scrollbar.
/// </summary>
public bool HandleInput public bool HandleInput
{ {
get => handleInput; get => handleInput;
@ -180,10 +182,24 @@ namespace osu.Game.Screens.Ranking
public override bool PropagateNonPositionalInputSubTree => HandleInput && base.PropagateNonPositionalInputSubTree; public override bool PropagateNonPositionalInputSubTree => HandleInput && base.PropagateNonPositionalInputSubTree;
/// <summary>
/// Enumerates all <see cref="ScorePanel"/>s contained in this <see cref="ScorePanelList"/>.
/// </summary>
/// <returns></returns>
public IEnumerable<ScorePanel> GetScorePanels() => flow.Select(t => t.Panel); public IEnumerable<ScorePanel> GetScorePanels() => flow.Select(t => t.Panel);
/// <summary>
/// Finds the <see cref="ScorePanel"/> corresponding to a <see cref="ScoreInfo"/>.
/// </summary>
/// <param name="score">The <see cref="ScoreInfo"/> to find the corresponding <see cref="ScorePanel"/> for.</param>
/// <returns>The <see cref="ScorePanel"/>.</returns>
public ScorePanel GetPanelForScore(ScoreInfo score) => flow.Single(t => t.Panel.Score == score).Panel; public ScorePanel GetPanelForScore(ScoreInfo score) => flow.Single(t => t.Panel.Score == score).Panel;
/// <summary>
/// Detaches a <see cref="ScorePanel"/> from its <see cref="ScorePanelTrackingContainer"/>, allowing the panel to be moved elsewhere in the hierarchy.
/// </summary>
/// <param name="panel">The <see cref="ScorePanel"/> to detach.</param>
/// <exception cref="InvalidOperationException">If <paramref name="panel"/> is not a part of this <see cref="ScorePanelList"/>.</exception>
public void Detach(ScorePanel panel) public void Detach(ScorePanel panel)
{ {
var container = flow.FirstOrDefault(t => t.Panel == panel); var container = flow.FirstOrDefault(t => t.Panel == panel);
@ -193,6 +209,11 @@ namespace osu.Game.Screens.Ranking
container.Detach(); container.Detach();
} }
/// <summary>
/// Attaches a <see cref="ScorePanel"/> to its <see cref="ScorePanelTrackingContainer"/> in this <see cref="ScorePanelList"/>.
/// </summary>
/// <param name="panel">The <see cref="ScorePanel"/> to attach.</param>
/// <exception cref="InvalidOperationException">If <paramref name="panel"/> is not a part of this <see cref="ScorePanelList"/>.</exception>
public void Attach(ScorePanel panel) public void Attach(ScorePanel panel)
{ {
var container = flow.FirstOrDefault(t => t.Panel == panel); var container = flow.FirstOrDefault(t => t.Panel == panel);

View File

@ -6,16 +6,27 @@ using osu.Framework.Graphics.Containers;
namespace osu.Game.Screens.Ranking namespace osu.Game.Screens.Ranking
{ {
/// <summary>
/// A <see cref="CompositeDrawable"/> which tracks the size of a <see cref="ScorePanel"/>, to which the <see cref="ScorePanel"/> can be added or removed.
/// </summary>
public class ScorePanelTrackingContainer : CompositeDrawable public class ScorePanelTrackingContainer : CompositeDrawable
{ {
/// <summary>
/// The <see cref="ScorePanel"/> that created this <see cref="ScorePanelTrackingContainer"/>.
/// </summary>
public readonly ScorePanel Panel; public readonly ScorePanel Panel;
public ScorePanelTrackingContainer(ScorePanel panel) internal ScorePanelTrackingContainer(ScorePanel panel)
{ {
Panel = panel; Panel = panel;
Attach(); Attach();
} }
/// <summary>
/// Detaches the <see cref="ScorePanel"/> from this <see cref="ScorePanelTrackingContainer"/>, removing it as a child.
/// This <see cref="ScorePanelTrackingContainer"/> will continue tracking any size changes.
/// </summary>
/// <exception cref="InvalidOperationException">If the <see cref="ScorePanel"/> is already detached.</exception>
public void Detach() public void Detach()
{ {
if (InternalChildren.Count == 0) if (InternalChildren.Count == 0)
@ -24,6 +35,10 @@ namespace osu.Game.Screens.Ranking
RemoveInternal(Panel); RemoveInternal(Panel);
} }
/// <summary>
/// Attaches the <see cref="ScorePanel"/> to this <see cref="ScorePanelTrackingContainer"/>, adding it as a child.
/// </summary>
/// <exception cref="InvalidOperationException">If the <see cref="ScorePanel"/> is already attached.</exception>
public void Attach() public void Attach()
{ {
if (InternalChildren.Count > 0) if (InternalChildren.Count > 0)

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Diagnostics.CodeAnalysis;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -11,13 +12,16 @@ using osuTK;
namespace osu.Game.Screens.Ranking.Statistics namespace osu.Game.Screens.Ranking.Statistics
{ {
internal class StatisticContainer : Container /// <summary>
/// Wraps a <see cref="StatisticItem"/> to add a header and suitable layout for use in <see cref="ResultsScreen"/>.
/// </summary>
internal class StatisticContainer : CompositeDrawable
{ {
protected override Container<Drawable> Content => content; /// <summary>
/// Creates a new <see cref="StatisticContainer"/>.
private readonly Container content; /// </summary>
/// <param name="item">The <see cref="StatisticItem"/> to display.</param>
public StatisticContainer(string name) public StatisticContainer([NotNull] StatisticItem item)
{ {
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
@ -50,7 +54,7 @@ namespace osu.Game.Screens.Ranking.Statistics
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
Text = name, Text = item.Name,
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold),
} }
} }
@ -58,11 +62,12 @@ namespace osu.Game.Screens.Ranking.Statistics
}, },
new Drawable[] new Drawable[]
{ {
content = new Container new Container
{ {
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Top = 15 } Margin = new MarginPadding { Top = 15 },
Child = item.Content
} }
}, },
}, },

View File

@ -30,9 +30,9 @@ namespace osu.Game.Screens.Ranking.Statistics
/// <summary> /// <summary>
/// Creates a new <see cref="StatisticItem"/>, to be displayed inside a <see cref="StatisticRow"/> in the results screen. /// Creates a new <see cref="StatisticItem"/>, to be displayed inside a <see cref="StatisticRow"/> in the results screen.
/// </summary> /// </summary>
/// <param name="name">The name of this item.</param> /// <param name="name">The name of the item.</param>
/// <param name="content">The <see cref="Drawable"/> content to be displayed.</param> /// <param name="content">The <see cref="Drawable"/> content to be displayed.</param>
/// <param name="dimension">The <see cref="Dimension"/> of this row. This can be thought of as the column dimension of an encompassing <see cref="GridContainer"/>.</param> /// <param name="dimension">The <see cref="Dimension"/> of this item. This can be thought of as the column dimension of an encompassing <see cref="GridContainer"/>.</param>
public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null) public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null)
{ {
Name = name; Name = name;

View File

@ -83,10 +83,7 @@ namespace osu.Game.Screens.Ranking.Statistics
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Content = new[] Content = new[]
{ {
row.Columns?.Select(c => new StatisticContainer(c.Name) row.Columns?.Select(c => new StatisticContainer(c)).Cast<Drawable>().ToArray()
{
Child = c.Content
}).Cast<Drawable>().ToArray()
}, },
ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0) ColumnDimensions = Enumerable.Range(0, row.Columns?.Length ?? 0)
.Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(), .Select(i => row.Columns[i].Dimension ?? new Dimension()).ToArray(),
@ -105,8 +102,8 @@ namespace osu.Game.Screens.Ranking.Statistics
} }
} }
protected override void PopIn() => this.FadeIn(); protected override void PopIn() => this.FadeIn(150, Easing.OutQuint);
protected override void PopOut() => this.FadeOut(); protected override void PopOut() => this.FadeOut(150, Easing.OutQuint);
} }
} }