1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 01:33:21 +08:00

Refactor beatmap info wedge to not fully refresh on star difficulty change

Makes it look awkward when changing difficulty via mod settings for
example.

Now the changes should instead only affect the displayed components which consume it
directly.
This commit is contained in:
Salman Ahmed 2021-08-17 04:29:15 +03:00
parent 32ba525555
commit b419ea716b

View File

@ -21,6 +21,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -38,6 +39,8 @@ namespace osu.Game.Screens.Select
public const float BORDER_THICKNESS = 2.5f; public const float BORDER_THICKNESS = 2.5f;
private const float shear_width = 36.75f; private const float shear_width = 36.75f;
private const float transition_duration = 250;
private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0); private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0);
[Resolved] [Resolved]
@ -46,11 +49,6 @@ namespace osu.Game.Screens.Select
[Resolved] [Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; } private IBindable<IReadOnlyList<Mod>> mods { get; set; }
[Resolved]
private BeatmapDifficultyCache difficultyCache { get; set; }
private IBindable<StarDifficulty?> beatmapDifficulty;
protected Container DisplayedContent { get; private set; } protected Container DisplayedContent { get; private set; }
protected WedgeInfoText Info { get; private set; } protected WedgeInfoText Info { get; private set; }
@ -81,20 +79,18 @@ namespace osu.Game.Screens.Select
{ {
this.MoveToX(0, 800, Easing.OutQuint); this.MoveToX(0, 800, Easing.OutQuint);
this.RotateTo(0, 800, Easing.OutQuint); this.RotateTo(0, 800, Easing.OutQuint);
this.FadeIn(250); this.FadeIn(transition_duration);
} }
protected override void PopOut() protected override void PopOut()
{ {
this.MoveToX(-100, 800, Easing.In); this.MoveToX(-100, 800, Easing.In);
this.RotateTo(10, 800, Easing.In); this.RotateTo(10, 800, Easing.In);
this.FadeOut(500, Easing.In); this.FadeOut(transition_duration * 2, Easing.In);
} }
private WorkingBeatmap beatmap; private WorkingBeatmap beatmap;
private CancellationTokenSource cancellationSource;
public WorkingBeatmap Beatmap public WorkingBeatmap Beatmap
{ {
get => beatmap; get => beatmap;
@ -103,12 +99,6 @@ namespace osu.Game.Screens.Select
if (beatmap == value) return; if (beatmap == value) return;
beatmap = value; beatmap = value;
cancellationSource?.Cancel();
cancellationSource = new CancellationTokenSource();
beatmapDifficulty?.UnbindAll();
beatmapDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token);
beatmapDifficulty.BindValueChanged(_ => updateDisplay());
updateDisplay(); updateDisplay();
} }
@ -128,7 +118,7 @@ namespace osu.Game.Screens.Select
{ {
State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible; State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible;
DisplayedContent?.FadeOut(250); DisplayedContent?.FadeOut(transition_duration);
DisplayedContent?.Expire(); DisplayedContent?.Expire();
DisplayedContent = null; DisplayedContent = null;
} }
@ -147,7 +137,7 @@ namespace osu.Game.Screens.Select
Children = new Drawable[] Children = new Drawable[]
{ {
new BeatmapInfoWedgeBackground(beatmap), new BeatmapInfoWedgeBackground(beatmap),
Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value ?? new StarDifficulty()), Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value),
} }
}, loaded => }, loaded =>
{ {
@ -160,12 +150,6 @@ namespace osu.Game.Screens.Select
} }
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
cancellationSource?.Cancel();
}
public class WedgeInfoText : Container public class WedgeInfoText : Container
{ {
public OsuSpriteText VersionLabel { get; private set; } public OsuSpriteText VersionLabel { get; private set; }
@ -174,6 +158,9 @@ namespace osu.Game.Screens.Select
public BeatmapSetOnlineStatusPill StatusPill { get; private set; } public BeatmapSetOnlineStatusPill StatusPill { get; private set; }
public FillFlowContainer MapperContainer { get; private set; } public FillFlowContainer MapperContainer { get; private set; }
private DifficultyColourBar difficultyColourBar;
private StarRatingDisplay starRatingDisplay;
private ILocalisedBindableString titleBinding; private ILocalisedBindableString titleBinding;
private ILocalisedBindableString artistBinding; private ILocalisedBindableString artistBinding;
private FillFlowContainer infoLabelContainer; private FillFlowContainer infoLabelContainer;
@ -182,20 +169,21 @@ namespace osu.Game.Screens.Select
private readonly WorkingBeatmap beatmap; private readonly WorkingBeatmap beatmap;
private readonly RulesetInfo ruleset; private readonly RulesetInfo ruleset;
private readonly IReadOnlyList<Mod> mods; private readonly IReadOnlyList<Mod> mods;
private readonly StarDifficulty starDifficulty;
private ModSettingChangeTracker settingChangeTracker; private ModSettingChangeTracker settingChangeTracker;
public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList<Mod> mods, StarDifficulty difficulty) public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList<Mod> mods)
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset; ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset;
this.mods = mods; this.mods = mods;
starDifficulty = difficulty;
} }
private CancellationTokenSource cancellationSource;
private IBindable<StarDifficulty?> starDifficulty;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(LocalisationManager localisation) private void load(LocalisationManager localisation, BeatmapDifficultyCache difficultyCache)
{ {
var beatmapInfo = beatmap.BeatmapInfo; var beatmapInfo = beatmap.BeatmapInfo;
var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
@ -207,7 +195,7 @@ namespace osu.Game.Screens.Select
Children = new Drawable[] Children = new Drawable[]
{ {
new DifficultyColourBar(starDifficulty) difficultyColourBar = new DifficultyColourBar
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Y,
Width = 20, Width = 20,
@ -241,14 +229,15 @@ namespace osu.Game.Screens.Select
Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, Padding = new MarginPadding { Top = 14, Right = shear_width / 2 },
AutoSizeAxes = Axes.Both, AutoSizeAxes = Axes.Both,
Shear = wedged_container_shear, Shear = wedged_container_shear,
Children = new[] Children = new Drawable[]
{ {
createStarRatingDisplay(starDifficulty).With(display => starRatingDisplay = new StarRatingDisplay(default)
{ {
display.Anchor = Anchor.TopRight; Anchor = Anchor.TopRight,
display.Origin = Anchor.TopRight; Origin = Anchor.TopRight,
display.Shear = -wedged_container_shear; Shear = -wedged_container_shear,
}), Alpha = 0f,
},
StatusPill = new BeatmapSetOnlineStatusPill StatusPill = new BeatmapSetOnlineStatusPill
{ {
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,
@ -304,6 +293,15 @@ namespace osu.Game.Screens.Select
titleBinding.BindValueChanged(_ => setMetadata(metadata.Source)); titleBinding.BindValueChanged(_ => setMetadata(metadata.Source));
artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true); artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true);
starDifficulty = difficultyCache.GetBindableDifficulty(beatmapInfo, (cancellationSource = new CancellationTokenSource()).Token);
starDifficulty.BindValueChanged(s =>
{
difficultyColourBar.Current.Value = s.NewValue ?? default;
starRatingDisplay.FadeIn(transition_duration);
starRatingDisplay.Current.Value = s.NewValue ?? default;
});
// no difficulty means it can't have a status to show // no difficulty means it can't have a status to show
if (beatmapInfo.Version == null) if (beatmapInfo.Version == null)
StatusPill.Hide(); StatusPill.Hide();
@ -311,13 +309,6 @@ namespace osu.Game.Screens.Select
addInfoLabels(); addInfoLabels();
} }
private static Drawable createStarRatingDisplay(StarDifficulty difficulty) => difficulty.Stars > 0
? new StarRatingDisplay(difficulty)
{
Margin = new MarginPadding { Bottom = 5 }
}
: Empty();
private void setMetadata(string source) private void setMetadata(string source)
{ {
ArtistLabel.Text = artistBinding.Value; ArtistLabel.Text = artistBinding.Value;
@ -429,6 +420,7 @@ namespace osu.Game.Screens.Select
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
settingChangeTracker?.Dispose(); settingChangeTracker?.Dispose();
cancellationSource?.Cancel();
} }
public class InfoLabel : Container, IHasTooltip public class InfoLabel : Container, IHasTooltip
@ -490,41 +482,53 @@ namespace osu.Game.Screens.Select
} }
} }
private class DifficultyColourBar : Container public class DifficultyColourBar : Container, IHasCurrentValue<StarDifficulty>
{ {
private readonly StarDifficulty difficulty; private readonly BindableWithCurrent<StarDifficulty> current = new BindableWithCurrent<StarDifficulty>();
public DifficultyColourBar(StarDifficulty difficulty) public Bindable<StarDifficulty> Current
{ {
this.difficulty = difficulty; get => current.Current;
set => current.Current = value;
} }
[Resolved]
private OsuColour colours { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load()
{ {
const float full_opacity_ratio = 0.7f; const float full_opacity_ratio = 0.7f;
var difficultyColour = colours.ForStarDifficulty(difficulty.Stars);
Children = new Drawable[] Children = new Drawable[]
{ {
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = difficultyColour,
Width = full_opacity_ratio, Width = full_opacity_ratio,
}, },
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both, RelativePositionAxes = Axes.Both,
Colour = difficultyColour,
Alpha = 0.5f, Alpha = 0.5f,
X = full_opacity_ratio, X = full_opacity_ratio,
Width = 1 - full_opacity_ratio, Width = 1 - full_opacity_ratio,
} }
}; };
} }
protected override void LoadComplete()
{
base.LoadComplete();
Current.BindValueChanged(c =>
{
this.FadeColour(colours.ForStarDifficulty(c.NewValue.Stars), transition_duration, Easing.OutQuint);
}, true);
FinishTransforms(true);
}
} }
} }
} }