Merge branch 'master' into tracked-hud-visibility-settings

This commit is contained in:
Dan Balasescu 2020-10-30 14:58:45 +09:00 committed by GitHub
commit b14291a312
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 36 deletions

View File

@ -35,6 +35,7 @@ namespace osu.Game.Rulesets.Mania.Tests
objects.Add(new Note { StartTime = time });
// don't hit the first note
if (i > 0)
{
frames.Add(new ManiaReplayFrame(time + 10, ManiaAction.Key1));

View File

@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.Ranking
private void addPanelStep(ScoreInfo score, PanelState state = PanelState.Expanded) => AddStep("add panel", () =>
{
Child = panel = new ScorePanel(score)
Child = panel = new ScorePanel(score, true)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -29,6 +29,8 @@ namespace osu.Game.Screens.Ranking.Expanded
private const float padding = 10;
private readonly ScoreInfo score;
private readonly bool withFlair;
private readonly List<StatisticDisplay> statisticDisplays = new List<StatisticDisplay>();
private FillFlowContainer starAndModDisplay;
@ -41,9 +43,11 @@ namespace osu.Game.Screens.Ranking.Expanded
/// Creates a new <see cref="ExpandedPanelMiddleContent"/>.
/// </summary>
/// <param name="score">The score to display.</param>
public ExpandedPanelMiddleContent(ScoreInfo score)
/// <param name="withFlair">Whether to add flair for a new score being set.</param>
public ExpandedPanelMiddleContent(ScoreInfo score, bool withFlair = false)
{
this.score = score;
this.withFlair = withFlair;
RelativeSizeAxes = Axes.Both;
Masking = true;
@ -266,6 +270,9 @@ namespace osu.Game.Screens.Ranking.Expanded
delay += 200;
}
}
if (!withFlair)
FinishTransforms(true);
});
}
}

View File

@ -149,7 +149,7 @@ namespace osu.Game.Screens.Ranking
};
if (Score != null)
ScorePanelList.AddScore(Score);
ScorePanelList.AddScore(Score, true);
if (player != null && allowRetry)
{

View File

@ -85,6 +85,8 @@ namespace osu.Game.Screens.Ranking
public readonly ScoreInfo Score;
private bool displayWithFlair;
private Container content;
private Container topLayerContainer;
@ -97,9 +99,10 @@ namespace osu.Game.Screens.Ranking
private Container middleLayerContentContainer;
private Drawable middleLayerContent;
public ScorePanel(ScoreInfo score)
public ScorePanel(ScoreInfo score, bool isNewLocalScore = false)
{
Score = score;
displayWithFlair = isNewLocalScore;
}
[BackgroundDependencyLoader]
@ -188,7 +191,7 @@ namespace osu.Game.Screens.Ranking
state = value;
if (LoadState >= LoadState.Ready)
if (IsLoaded)
updateState();
StateChanged?.Invoke(value);
@ -209,7 +212,10 @@ namespace osu.Game.Screens.Ranking
middleLayerBackground.FadeColour(expanded_middle_layer_colour, resize_duration, Easing.OutQuint);
topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User).With(d => d.Alpha = 0));
middleLayerContentContainer.Add(middleLayerContent = new ExpandedPanelMiddleContent(Score).With(d => d.Alpha = 0));
middleLayerContentContainer.Add(middleLayerContent = new ExpandedPanelMiddleContent(Score, displayWithFlair).With(d => d.Alpha = 0));
// only the first expanded display should happen with flair.
displayWithFlair = false;
break;
case PanelState.Contracted:

View File

@ -95,9 +95,10 @@ namespace osu.Game.Screens.Ranking
/// Adds a <see cref="ScoreInfo"/> to this list.
/// </summary>
/// <param name="score">The <see cref="ScoreInfo"/> to add.</param>
public ScorePanel AddScore(ScoreInfo score)
/// <param name="isNewLocalScore">Whether this is a score that has just been achieved locally. Controls whether flair is added to the display or not.</param>
public ScorePanel AddScore(ScoreInfo score, bool isNewLocalScore = false)
{
var panel = new ScorePanel(score)
var panel = new ScorePanel(score, isNewLocalScore)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
@ -117,19 +118,24 @@ namespace osu.Game.Screens.Ranking
d.Origin = Anchor.Centre;
}));
if (SelectedScore.Value == score)
selectedScoreChanged(new ValueChangedEvent<ScoreInfo>(SelectedScore.Value, SelectedScore.Value));
else
if (IsLoaded)
{
// We want the scroll position to remain relative to the expanded panel. When a new panel is added after the expanded panel, nothing needs to be done.
// But when a panel is added before the expanded panel, we need to offset the scroll position by the width of the new panel.
if (expandedPanel != null && flow.GetPanelIndex(score) < flow.GetPanelIndex(expandedPanel.Score))
if (SelectedScore.Value == score)
{
// A somewhat hacky property is used here because we need to:
// 1) Scroll after the scroll container's visible range is updated.
// 2) Scroll before the scroll container's scroll position is updated.
// Without this, we would have a 1-frame positioning error which looks very jarring.
scroll.InstantScrollTarget = (scroll.InstantScrollTarget ?? scroll.Target) + ScorePanel.CONTRACTED_WIDTH + panel_spacing;
SelectedScore.TriggerChange();
}
else
{
// We want the scroll position to remain relative to the expanded panel. When a new panel is added after the expanded panel, nothing needs to be done.
// But when a panel is added before the expanded panel, we need to offset the scroll position by the width of the new panel.
if (expandedPanel != null && flow.GetPanelIndex(score) < flow.GetPanelIndex(expandedPanel.Score))
{
// A somewhat hacky property is used here because we need to:
// 1) Scroll after the scroll container's visible range is updated.
// 2) Scroll before the scroll container's scroll position is updated.
// Without this, we would have a 1-frame positioning error which looks very jarring.
scroll.InstantScrollTarget = (scroll.InstantScrollTarget ?? scroll.Target) + ScorePanel.CONTRACTED_WIDTH + panel_spacing;
}
}
}
@ -142,11 +148,15 @@ namespace osu.Game.Screens.Ranking
/// <param name="score">The <see cref="ScoreInfo"/> to present.</param>
private void selectedScoreChanged(ValueChangedEvent<ScoreInfo> score)
{
// Contract the old panel.
foreach (var t in flow.Where(t => t.Panel.Score == score.OldValue))
// avoid contracting panels unnecessarily when TriggerChange is fired manually.
if (score.OldValue != score.NewValue)
{
t.Panel.State = PanelState.Contracted;
t.Margin = new MarginPadding();
// Contract the old panel.
foreach (var t in flow.Where(t => t.Panel.Score == score.OldValue))
{
t.Panel.State = PanelState.Contracted;
t.Margin = new MarginPadding();
}
}
// Find the panel corresponding to the new score.
@ -162,12 +172,16 @@ namespace osu.Game.Screens.Ranking
expandedTrackingComponent.Margin = new MarginPadding { Horizontal = expanded_panel_spacing };
expandedPanel.State = PanelState.Expanded;
// Scroll to the new panel. This is done manually since we need:
// 1) To scroll after the scroll container's visible range is updated.
// 2) To account for the centre anchor/origins of panels.
// In the end, it's easier to compute the scroll position manually.
float scrollOffset = flow.GetPanelIndex(expandedPanel.Score) * (ScorePanel.CONTRACTED_WIDTH + panel_spacing);
scroll.ScrollTo(scrollOffset);
// requires schedule after children to ensure the flow (and thus ScrollContainer's ScrollableExtent) has been updated.
ScheduleAfterChildren(() =>
{
// Scroll to the new panel. This is done manually since we need:
// 1) To scroll after the scroll container's visible range is updated.
// 2) To account for the centre anchor/origins of panels.
// In the end, it's easier to compute the scroll position manually.
float scrollOffset = flow.GetPanelIndex(expandedPanel.Score) * (ScorePanel.CONTRACTED_WIDTH + panel_spacing);
scroll.ScrollTo(scrollOffset);
});
}
protected override void Update()

View File

@ -180,9 +180,8 @@ namespace osu.Game.Tests.Beatmaps
private readonly BeatmapInfo skinBeatmapInfo;
private readonly IResourceStore<byte[]> resourceStore;
public TestWorkingBeatmap(BeatmapInfo skinBeatmapInfo, IResourceStore<byte[]> resourceStore, IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio,
double length = 60000)
: base(beatmap, storyboard, referenceClock, audio, length)
public TestWorkingBeatmap(BeatmapInfo skinBeatmapInfo, IResourceStore<byte[]> resourceStore, IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio)
: base(beatmap, storyboard, referenceClock, audio)
{
this.skinBeatmapInfo = skinBeatmapInfo;
this.resourceStore = resourceStore;

View File

@ -23,6 +23,7 @@ using osu.Game.Online.API;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Screens;
using osu.Game.Storyboards;
@ -222,18 +223,23 @@ namespace osu.Game.Tests.Visual
/// <param name="storyboard">The storyboard.</param>
/// <param name="referenceClock">An optional clock which should be used instead of a stopwatch for virtual time progression.</param>
/// <param name="audio">Audio manager. Required if a reference clock isn't provided.</param>
/// <param name="length">The length of the returned virtual track.</param>
public ClockBackedTestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio, double length = 60000)
public ClockBackedTestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio)
: base(beatmap, storyboard, audio)
{
double trackLength = 60000;
if (beatmap.HitObjects.Count > 0)
// add buffer after last hitobject to allow for final replay frames etc.
trackLength = Math.Max(trackLength, beatmap.HitObjects.Max(h => h.GetEndTime()) + 2000);
if (referenceClock != null)
{
store = new TrackVirtualStore(referenceClock);
audio.AddItem(store);
track = store.GetVirtual(length);
track = store.GetVirtual(trackLength);
}
else
track = audio?.Tracks.GetVirtual(length);
track = audio?.Tracks.GetVirtual(trackLength);
}
~ClockBackedTestWorkingBeatmap()