From b419ea716b307eb54fca5892024e5066b81920f0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:29:15 +0300 Subject: [PATCH] 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. --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 104 ++++++++++---------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 5b4e077100..678e7d5d73 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -21,6 +21,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Game.Configuration; @@ -38,6 +39,8 @@ namespace osu.Game.Screens.Select public const float BORDER_THICKNESS = 2.5f; 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); [Resolved] @@ -46,11 +49,6 @@ namespace osu.Game.Screens.Select [Resolved] private IBindable> mods { get; set; } - [Resolved] - private BeatmapDifficultyCache difficultyCache { get; set; } - - private IBindable beatmapDifficulty; - protected Container DisplayedContent { 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.RotateTo(0, 800, Easing.OutQuint); - this.FadeIn(250); + this.FadeIn(transition_duration); } protected override void PopOut() { this.MoveToX(-100, 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 CancellationTokenSource cancellationSource; - public WorkingBeatmap Beatmap { get => beatmap; @@ -103,12 +99,6 @@ namespace osu.Game.Screens.Select if (beatmap == value) return; beatmap = value; - cancellationSource?.Cancel(); - cancellationSource = new CancellationTokenSource(); - - beatmapDifficulty?.UnbindAll(); - beatmapDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token); - beatmapDifficulty.BindValueChanged(_ => updateDisplay()); updateDisplay(); } @@ -128,7 +118,7 @@ namespace osu.Game.Screens.Select { State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible; - DisplayedContent?.FadeOut(250); + DisplayedContent?.FadeOut(transition_duration); DisplayedContent?.Expire(); DisplayedContent = null; } @@ -147,7 +137,7 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { new BeatmapInfoWedgeBackground(beatmap), - Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value ?? new StarDifficulty()), + Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value), } }, 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 OsuSpriteText VersionLabel { get; private set; } @@ -174,6 +158,9 @@ namespace osu.Game.Screens.Select public BeatmapSetOnlineStatusPill StatusPill { get; private set; } public FillFlowContainer MapperContainer { get; private set; } + private DifficultyColourBar difficultyColourBar; + private StarRatingDisplay starRatingDisplay; + private ILocalisedBindableString titleBinding; private ILocalisedBindableString artistBinding; private FillFlowContainer infoLabelContainer; @@ -182,20 +169,21 @@ namespace osu.Game.Screens.Select private readonly WorkingBeatmap beatmap; private readonly RulesetInfo ruleset; private readonly IReadOnlyList mods; - private readonly StarDifficulty starDifficulty; private ModSettingChangeTracker settingChangeTracker; - public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList mods, StarDifficulty difficulty) + public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList mods) { this.beatmap = beatmap; ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset; this.mods = mods; - starDifficulty = difficulty; } + private CancellationTokenSource cancellationSource; + private IBindable starDifficulty; + [BackgroundDependencyLoader] - private void load(LocalisationManager localisation) + private void load(LocalisationManager localisation, BeatmapDifficultyCache difficultyCache) { var beatmapInfo = beatmap.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); @@ -207,7 +195,7 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { - new DifficultyColourBar(starDifficulty) + difficultyColourBar = new DifficultyColourBar { RelativeSizeAxes = Axes.Y, Width = 20, @@ -241,14 +229,15 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, Shear = wedged_container_shear, - Children = new[] + Children = new Drawable[] { - createStarRatingDisplay(starDifficulty).With(display => + starRatingDisplay = new StarRatingDisplay(default) { - display.Anchor = Anchor.TopRight; - display.Origin = Anchor.TopRight; - display.Shear = -wedged_container_shear; - }), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Shear = -wedged_container_shear, + Alpha = 0f, + }, StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.TopRight, @@ -304,6 +293,15 @@ namespace osu.Game.Screens.Select titleBinding.BindValueChanged(_ => setMetadata(metadata.Source)); 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 if (beatmapInfo.Version == null) StatusPill.Hide(); @@ -311,13 +309,6 @@ namespace osu.Game.Screens.Select addInfoLabels(); } - private static Drawable createStarRatingDisplay(StarDifficulty difficulty) => difficulty.Stars > 0 - ? new StarRatingDisplay(difficulty) - { - Margin = new MarginPadding { Bottom = 5 } - } - : Empty(); - private void setMetadata(string source) { ArtistLabel.Text = artistBinding.Value; @@ -429,6 +420,7 @@ namespace osu.Game.Screens.Select { base.Dispose(isDisposing); settingChangeTracker?.Dispose(); + cancellationSource?.Cancel(); } public class InfoLabel : Container, IHasTooltip @@ -490,41 +482,53 @@ namespace osu.Game.Screens.Select } } - private class DifficultyColourBar : Container + public class DifficultyColourBar : Container, IHasCurrentValue { - private readonly StarDifficulty difficulty; + private readonly BindableWithCurrent current = new BindableWithCurrent(); - public DifficultyColourBar(StarDifficulty difficulty) + public Bindable Current { - this.difficulty = difficulty; + get => current.Current; + set => current.Current = value; } + [Resolved] + private OsuColour colours { get; set; } + [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { const float full_opacity_ratio = 0.7f; - var difficultyColour = colours.ForStarDifficulty(difficulty.Stars); - Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = difficultyColour, Width = full_opacity_ratio, }, new Box { RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Both, - Colour = difficultyColour, Alpha = 0.5f, X = 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); + } } } }