Skip to content

Commit

Permalink
Merge pull request #23718 from peppy/tidy-results-grid-usage
Browse files Browse the repository at this point in the history
Tidy up results screen statistic item flow
  • Loading branch information
bdach committed Jun 4, 2023
2 parents 5114934 + 331e90f commit d0167cb
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 234 deletions.
44 changes: 13 additions & 31 deletions osu.Game.Rulesets.Mania/ManiaRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,41 +389,23 @@ public override LocalisableString GetDisplayNameForHitResult(HitResult result)
return base.GetDisplayNameForHitResult(result);
}

public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{
new StatisticRow
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
Columns = new[]
{
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(score.HitEvents)
{
Columns = new[]
{
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(score.HitEvents)
{
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
Columns = new[]
{
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
new AverageHitError(score.HitEvents),
new UnstableRate(score.HitEvents)
}), true)
}
}
new AverageHitError(score.HitEvents),
new UnstableRate(score.HitEvents)
}), true)
};

public override IRulesetFilterCriteria CreateRulesetFilterCriteria()
Expand Down
58 changes: 17 additions & 41 deletions osu.Game.Rulesets.Osu/OsuRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,56 +291,32 @@ public override LocalisableString GetDisplayNameForHitResult(HitResult result)
return base.GetDisplayNameForHitResult(result);
}

public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
{
var timedHitEvents = score.HitEvents.Where(e => e.HitObject is HitCircle && !(e.HitObject is SliderTailCircle)).ToList();

return new[]
{
new StatisticRow
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
Columns = new[]
{
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(timedHitEvents)
{
Columns = new[]
{
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(timedHitEvents)
{
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
new StatisticItem("Accuracy Heatmap", () => new AccuracyHeatmap(score, playableBeatmap)
{
Columns = new[]
{
new StatisticItem("Accuracy Heatmap", () => new AccuracyHeatmap(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
Columns = new[]
{
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
new AverageHitError(timedHitEvents),
new UnstableRate(timedHitEvents)
}), true)
}
}
new AverageHitError(timedHitEvents),
new UnstableRate(timedHitEvents)
}), true)
};
}

Expand Down
44 changes: 13 additions & 31 deletions osu.Game.Rulesets.Taiko/TaikoRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,45 +229,27 @@ public override LocalisableString GetDisplayNameForHitResult(HitResult result)
return base.GetDisplayNameForHitResult(result);
}

public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
{
var timedHitEvents = score.HitEvents.Where(e => e.HitObject is Hit).ToList();

return new[]
{
new StatisticRow
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
Columns = new[]
{
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}),
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(timedHitEvents)
{
Columns = new[]
{
new StatisticItem("Timing Distribution", () => new HitEventTimingDistributionGraph(timedHitEvents)
{
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
}
},
new StatisticRow
RelativeSizeAxes = Axes.X,
Height = 250
}, true),
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
Columns = new[]
{
new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
{
new AverageHitError(timedHitEvents),
new UnstableRate(timedHitEvents)
}), true)
}
}
new AverageHitError(timedHitEvents),
new UnstableRate(timedHitEvents)
}), true)
};
}
}
Expand Down
65 changes: 10 additions & 55 deletions osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,78 +174,33 @@ public TestBeatmapConverter(IBeatmap beatmap)

private class TestRulesetAllStatsRequireHitEvents : TestRuleset
{
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => new[]
{
return new[]
{
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Requiring Hit Events 1",
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
}
},
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Requiring Hit Events 2",
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
}
}
};
}
new StatisticItem("Statistic Requiring Hit Events 1", () => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true),
new StatisticItem("Statistic Requiring Hit Events 2", () => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
};
}

private class TestRulesetNoStatsRequireHitEvents : TestRuleset
{
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
{
return new[]
{
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Not Requiring Hit Events 1",
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
}
},
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Not Requiring Hit Events 2",
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
}
}
new StatisticItem("Statistic Not Requiring Hit Events 1", () => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events")),
new StatisticItem("Statistic Not Requiring Hit Events 2", () => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
};
}
}

private class TestRulesetMixed : TestRuleset
{
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
{
return new[]
{
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Requiring Hit Events",
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
}
},
new StatisticRow
{
Columns = new[]
{
new StatisticItem("Statistic Not Requiring Hit Events",
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
}
}
new StatisticItem("Statistic Requiring Hit Events", () => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true),
new StatisticItem("Statistic Not Requiring Hit Events", () => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Rulesets/Ruleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,8 @@ protected Ruleset()
/// </summary>
/// <param name="score">The <see cref="ScoreInfo"/> to create the statistics for. The score is guaranteed to have <see cref="ScoreInfo.HitEvents"/> populated.</param>
/// <param name="playableBeatmap">The <see cref="IBeatmap"/>, converted for this <see cref="Ruleset"/> with all relevant <see cref="Mod"/>s applied.</param>
/// <returns>The <see cref="StatisticRow"/>s to display. Each <see cref="StatisticRow"/> may contain 0 or more <see cref="StatisticItem"/>.</returns>
public virtual StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty<StatisticRow>();
/// <returns>The <see cref="StatisticItem"/>s to display.</returns>
public virtual StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty<StatisticItem>();

/// <summary>
/// Get all valid <see cref="HitResult"/>s for this ruleset.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Ranking.Statistics
{
/// <summary>
/// Represents a table with simple statistics (ones that only need textual display).
/// Richer visualisations should be done with <see cref="StatisticRow"/>s and <see cref="StatisticItem"/>s.
/// Richer visualisations should be done with <see cref="StatisticItem"/>s.
/// </summary>
public partial class SimpleStatisticTable : CompositeDrawable
{
Expand Down
26 changes: 10 additions & 16 deletions osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,26 @@ public SoloStatisticsPanel(ScoreInfo achievedScore)

public Bindable<SoloStatisticsUpdate?> StatisticsUpdate { get; } = new Bindable<SoloStatisticsUpdate?>();

protected override ICollection<StatisticRow> CreateStatisticRows(ScoreInfo newScore, IBeatmap playableBeatmap)
protected override ICollection<StatisticItem> CreateStatisticItems(ScoreInfo newScore, IBeatmap playableBeatmap)
{
var rows = base.CreateStatisticRows(newScore, playableBeatmap);
var items = base.CreateStatisticItems(newScore, playableBeatmap);

if (newScore.UserID > 1
&& newScore.UserID == achievedScore.UserID
&& newScore.OnlineID > 0
&& newScore.OnlineID == achievedScore.OnlineID)
{
rows = rows.Append(new StatisticRow
items = items.Append(new StatisticItem("Overall Ranking", () => new OverallRanking
{
Columns = new[]
{
new StatisticItem("Overall Ranking", () => new OverallRanking
{
RelativeSizeAxes = Axes.X,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 0.5f,
StatisticsUpdate = { BindTarget = StatisticsUpdate }
})
}
}).ToArray();
RelativeSizeAxes = Axes.X,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 0.5f,
StatisticsUpdate = { BindTarget = StatisticsUpdate }
})).ToArray();
}

return rows;
return items;
}
}
}
12 changes: 2 additions & 10 deletions osu.Game/Screens/Ranking/Statistics/StatisticItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System;
using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;

namespace osu.Game.Screens.Ranking.Statistics
Expand All @@ -26,29 +25,22 @@ public class StatisticItem
/// </summary>
public readonly Func<Drawable> CreateContent;

/// <summary>
/// The <see cref="Dimension"/> of this row. This can be thought of as the column dimension of an encompassing <see cref="GridContainer"/>.
/// </summary>
public readonly Dimension Dimension;

/// <summary>
/// Whether this item requires hit events. If true, <see cref="CreateContent"/> will not be called if no hit events are available.
/// </summary>
public readonly bool RequiresHitEvents;

/// <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 in the results screen.
/// </summary>
/// <param name="name">The name of the item. Can be <see langword="null"/> to hide the item header.</param>
/// <param name="createContent">A function returning the <see cref="Drawable"/> content to be displayed.</param>
/// <param name="requiresHitEvents">Whether this item requires hit events. If true, <see cref="CreateContent"/> will not be called if no hit events are available.</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(LocalisableString name, [NotNull] Func<Drawable> createContent, bool requiresHitEvents = false, [CanBeNull] Dimension dimension = null)
public StatisticItem(LocalisableString name, [NotNull] Func<Drawable> createContent, bool requiresHitEvents = false)
{
Name = name;
RequiresHitEvents = requiresHitEvents;
CreateContent = createContent;
Dimension = dimension;
}
}
}

0 comments on commit d0167cb

Please sign in to comment.