1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 20:07:29 +08:00

Merge pull request #11425 from peppy/fix-transform-mutation-from-background

Fix transform mutation on background screens
This commit is contained in:
Dean Herbert 2021-01-06 20:01:42 +09:00 committed by GitHub
commit ddfa3254b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 153 additions and 65 deletions

View File

@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.Background
});
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Stop background preview", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.CheckBackgroundBlur(playerLoader.ExpectedBackgroundBlur));
}
/// <summary>
@ -106,6 +106,7 @@ namespace osu.Game.Tests.Visual.Background
public void TestStoryboardBackgroundVisibility()
{
performFullSetup();
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
createFakeStoryboard();
AddStep("Enable Storyboard", () =>
{
@ -198,8 +199,9 @@ namespace osu.Game.Tests.Visual.Background
})));
AddUntilStep("Wait for results is current", () => results.IsCurrentScreen());
AddUntilStep("Screen is undimmed, original background retained", () =>
songSelect.IsBackgroundUndimmed() && songSelect.IsBackgroundCurrent() && results.IsBlurCorrect());
songSelect.IsBackgroundUndimmed() && songSelect.IsBackgroundCurrent() && songSelect.CheckBackgroundBlur(results.ExpectedBackgroundBlur));
}
/// <summary>
@ -224,7 +226,7 @@ namespace osu.Game.Tests.Visual.Background
AddStep("Resume PlayerLoader", () => player.Restart());
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.CheckBackgroundBlur(playerLoader.ExpectedBackgroundBlur));
}
private void createFakeStoryboard() => AddStep("Create storyboard", () =>
@ -274,9 +276,11 @@ namespace osu.Game.Tests.Visual.Background
private class DummySongSelect : PlaySongSelect
{
private FadeAccessibleBackground background;
protected override BackgroundScreen CreateBackground()
{
FadeAccessibleBackground background = new FadeAccessibleBackground(Beatmap.Value);
background = new FadeAccessibleBackground(Beatmap.Value);
DimEnabled.BindTo(background.EnableUserDim);
return background;
}
@ -294,25 +298,27 @@ namespace osu.Game.Tests.Visual.Background
config.BindWith(OsuSetting.BlurLevel, BlurLevel);
}
public bool IsBackgroundDimmed() => ((FadeAccessibleBackground)Background).CurrentColour == OsuColour.Gray(1f - ((FadeAccessibleBackground)Background).CurrentDim);
public bool IsBackgroundDimmed() => background.CurrentColour == OsuColour.Gray(1f - background.CurrentDim);
public bool IsBackgroundUndimmed() => ((FadeAccessibleBackground)Background).CurrentColour == Color4.White;
public bool IsBackgroundUndimmed() => background.CurrentColour == Color4.White;
public bool IsUserBlurApplied() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR);
public bool IsUserBlurApplied() => background.CurrentBlur == new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR);
public bool IsUserBlurDisabled() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(0);
public bool IsUserBlurDisabled() => background.CurrentBlur == new Vector2(0);
public bool IsBackgroundInvisible() => ((FadeAccessibleBackground)Background).CurrentAlpha == 0;
public bool IsBackgroundInvisible() => background.CurrentAlpha == 0;
public bool IsBackgroundVisible() => ((FadeAccessibleBackground)Background).CurrentAlpha == 1;
public bool IsBackgroundVisible() => background.CurrentAlpha == 1;
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
public bool IsBlurCorrect() => background.CurrentBlur == new Vector2(BACKGROUND_BLUR);
public bool CheckBackgroundBlur(Vector2 expected) => background.CurrentBlur == expected;
/// <summary>
/// Make sure every time a screen gets pushed, the background doesn't get replaced
/// </summary>
/// <returns>Whether or not the original background (The one created in DummySongSelect) is still the current background</returns>
public bool IsBackgroundCurrent() => ((FadeAccessibleBackground)Background).IsCurrentScreen();
public bool IsBackgroundCurrent() => background?.IsCurrentScreen() == true;
}
private class FadeAccessibleResults : ResultsScreen
@ -324,12 +330,20 @@ namespace osu.Game.Tests.Visual.Background
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
public Vector2 ExpectedBackgroundBlur => new Vector2(BACKGROUND_BLUR);
}
private class LoadBlockingTestPlayer : TestPlayer
{
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
protected override BackgroundScreen CreateBackground() =>
new FadeAccessibleBackground(Beatmap.Value);
public override void OnEntering(IScreen last)
{
base.OnEntering(last);
ApplyToBackground(b => ReplacesBackground.BindTo(b.StoryboardReplacesBackground));
}
public new DimmableStoryboard DimmableStoryboard => base.DimmableStoryboard;
@ -354,15 +368,16 @@ namespace osu.Game.Tests.Visual.Background
Thread.Sleep(1);
StoryboardEnabled = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
ReplacesBackground.BindTo(Background.StoryboardReplacesBackground);
DrawableRuleset.IsPaused.BindTo(IsPaused);
}
}
private class TestPlayerLoader : PlayerLoader
{
private FadeAccessibleBackground background;
public VisualSettings VisualSettingsPos => VisualSettings;
public BackgroundScreen ScreenPos => Background;
public BackgroundScreen ScreenPos => background;
public TestPlayerLoader(Player player)
: base(() => player)
@ -371,9 +386,9 @@ namespace osu.Game.Tests.Visual.Background
public void TriggerOnHover() => OnHover(new HoverEvent(new InputState()));
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
public Vector2 ExpectedBackgroundBlur => new Vector2(BACKGROUND_BLUR);
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
protected override BackgroundScreen CreateBackground() => background = new FadeAccessibleBackground(Beatmap.Value);
}
private class FadeAccessibleBackground : BackgroundScreenBeatmap

View File

@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mods
public void ApplyToPlayer(Player player)
{
player.Background.EnableUserDim.Value = false;
player.ApplyToBackground(b => b.EnableUserDim.Value = false);
player.DimmableStoryboard.IgnoreUserSettings.Value = true;

View File

@ -34,6 +34,12 @@ namespace osu.Game.Screens
return false;
}
/// <summary>
/// Apply arbitrary changes to this background in a thread safe manner.
/// </summary>
/// <param name="action">The operation to perform.</param>
public void ApplyToBackground(Action<BackgroundScreen> action) => Schedule(() => action.Invoke(this));
protected override void Update()
{
base.Update();

View File

@ -444,11 +444,14 @@ namespace osu.Game.Screens.Edit
{
base.OnEntering(last);
// todo: temporary. we want to be applying dim using the UserDimContainer eventually.
Background.FadeColour(Color4.DarkGray, 500);
ApplyToBackground(b =>
{
// todo: temporary. we want to be applying dim using the UserDimContainer eventually.
b.FadeColour(Color4.DarkGray, 500);
Background.EnableUserDim.Value = false;
Background.BlurAmount.Value = 0;
b.EnableUserDim.Value = false;
b.BlurAmount.Value = 0;
});
resetTrack(true);
}
@ -480,7 +483,7 @@ namespace osu.Game.Screens.Edit
}
}
Background.FadeColour(Color4.White, 500);
ApplyToBackground(b => b.FadeColour(Color4.White, 500));
resetTrack();
return base.OnExiting(next);

View File

@ -127,11 +127,11 @@ namespace osu.Game.Screens.Menu
{
case ButtonSystemState.Initial:
case ButtonSystemState.Exit:
Background.FadeColour(Color4.White, 500, Easing.OutSine);
ApplyToBackground(b => b.FadeColour(Color4.White, 500, Easing.OutSine));
break;
default:
Background.FadeColour(OsuColour.Gray(0.8f), 500, Easing.OutSine);
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(0.8f), 500, Easing.OutSine));
break;
}
};
@ -256,7 +256,7 @@ namespace osu.Game.Screens.Menu
{
base.OnResuming(last);
(Background as BackgroundScreenDefault)?.Next();
ApplyToBackground(b => (b as BackgroundScreenDefault)?.Next());
// we may have consumed our preloaded instance, so let's make another.
preloadSongSelect();

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
@ -114,11 +115,17 @@ namespace osu.Game.Screens
Mods = screenDependencies.Mods;
}
protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen;
/// <summary>
/// The background created and owned by this screen. May be null if the background didn't change.
/// </summary>
[CanBeNull]
private BackgroundScreen ownedBackground;
private BackgroundScreen localBackground;
[CanBeNull]
private BackgroundScreen background;
[Resolved(canBeNull: true)]
[CanBeNull]
private BackgroundScreenStack backgroundStack { get; set; }
[Resolved(canBeNull: true)]
@ -140,6 +147,21 @@ namespace osu.Game.Screens
Activity.Value ??= InitialActivity;
}
/// <summary>
/// Apply arbitrary changes to the current background screen in a thread safe manner.
/// </summary>
/// <param name="action">The operation to perform.</param>
public void ApplyToBackground(Action<BackgroundScreen> action)
{
if (backgroundStack == null)
throw new InvalidOperationException("Attempted to apply to background without a background stack being available.");
if (background == null)
throw new InvalidOperationException("Attempted to apply to background before screen is pushed.");
background.ApplyToBackground(action);
}
public override void OnResuming(IScreen last)
{
if (PlayResumeSound)
@ -160,7 +182,16 @@ namespace osu.Game.Screens
{
applyArrivingDefaults(false);
backgroundStack?.Push(localBackground = CreateBackground());
backgroundStack?.Push(ownedBackground = CreateBackground());
background = backgroundStack?.CurrentScreen as BackgroundScreen;
if (background != ownedBackground)
{
// background may have not been replaced, at which point we don't want to track the background lifetime.
ownedBackground?.Dispose();
ownedBackground = null;
}
base.OnEntering(last);
}
@ -173,7 +204,7 @@ namespace osu.Game.Screens
if (base.OnExiting(next))
return true;
if (localBackground != null && backgroundStack?.CurrentScreen == localBackground)
if (ownedBackground != null && backgroundStack?.CurrentScreen == ownedBackground)
backgroundStack?.Exit();
return false;

View File

@ -24,7 +24,19 @@ namespace osu.Game.Screens.Play
Alpha = 0f;
}
public BackgroundScreenBeatmap DimmableBackground { get; set; }
private BackgroundScreenBeatmap dimmableBackground;
public BackgroundScreenBeatmap DimmableBackground
{
get => dimmableBackground;
set
{
dimmableBackground = value;
if (IsLoaded)
updateBackgroundFade();
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, IBindable<WorkingBeatmap> beatmap)
@ -75,11 +87,16 @@ namespace osu.Game.Screens.Play
protected override void PopIn()
{
DimmableBackground?.FadeColour(OsuColour.Gray(0.5f), FADE_DURATION, Easing.OutQuint);
updateBackgroundFade();
this.FadeIn(FADE_DURATION, Easing.OutQuint);
}
private void updateBackgroundFade()
{
DimmableBackground?.FadeColour(OsuColour.Gray(0.5f), FADE_DURATION, Easing.OutQuint);
}
protected override void PopOut() => this.FadeOut(FADE_DURATION);
}
}

View File

@ -721,15 +721,20 @@ namespace osu.Game.Screens.Play
.Delay(250)
.FadeIn(250);
Background.EnableUserDim.Value = true;
Background.BlurAmount.Value = 0;
ApplyToBackground(b =>
{
b.EnableUserDim.Value = true;
b.BlurAmount.Value = 0;
// bind component bindables.
b.IsBreakTime.BindTo(breakTracker.IsBreakTime);
b.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground);
});
// bind component bindables.
Background.IsBreakTime.BindTo(breakTracker.IsBreakTime);
HUDOverlay.IsBreakTime.BindTo(breakTracker.IsBreakTime);
DimmableStoryboard.IsBreakTime.BindTo(breakTracker.IsBreakTime);
Background.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground);
DimmableStoryboard.StoryboardReplacesBackground.BindTo(storyboardReplacesBackground);
storyboardReplacesBackground.Value = Beatmap.Value.Storyboard.ReplacesBackground && Beatmap.Value.Storyboard.HasDrawable;
@ -875,7 +880,7 @@ namespace osu.Game.Screens.Play
float fadeOutDuration = instant ? 0 : 250;
this.FadeOut(fadeOutDuration);
Background.EnableUserDim.Value = false;
ApplyToBackground(b => b.EnableUserDim.Value = false);
storyboardReplacesBackground.Value = false;
}

View File

@ -67,7 +67,7 @@ namespace osu.Game.Screens.Play
backgroundBrightnessReduction = value;
Background.FadeColour(OsuColour.Gray(backgroundBrightnessReduction ? 0.8f : 1), 200);
ApplyToBackground(b => b.FadeColour(OsuColour.Gray(backgroundBrightnessReduction ? 0.8f : 1), 200));
}
}
@ -176,12 +176,17 @@ namespace osu.Game.Screens.Play
{
base.OnEntering(last);
if (epilepsyWarning != null)
epilepsyWarning.DimmableBackground = Background;
ApplyToBackground(b =>
{
if (epilepsyWarning != null)
epilepsyWarning.DimmableBackground = b;
b?.FadeColour(Color4.White, 800, Easing.OutQuint);
});
Beatmap.Value.Track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment);
content.ScaleTo(0.7f);
Background?.FadeColour(Color4.White, 800, Easing.OutQuint);
contentIn();
@ -225,7 +230,8 @@ namespace osu.Game.Screens.Play
content.ScaleTo(0.7f, 150, Easing.InQuint);
this.FadeOut(150);
Background.EnableUserDim.Value = false;
ApplyToBackground(b => b.EnableUserDim.Value = false);
BackgroundBrightnessReduction = false;
Beatmap.Value.Track.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment);
@ -270,16 +276,22 @@ namespace osu.Game.Screens.Play
if (inputManager.HoveredDrawables.Contains(VisualSettings))
{
// Preview user-defined background dim and blur when hovered on the visual settings panel.
Background.EnableUserDim.Value = true;
Background.BlurAmount.Value = 0;
ApplyToBackground(b =>
{
b.EnableUserDim.Value = true;
b.BlurAmount.Value = 0;
});
BackgroundBrightnessReduction = false;
}
else
{
// Returns background dim and blur to the values specified by PlayerLoader.
Background.EnableUserDim.Value = false;
Background.BlurAmount.Value = BACKGROUND_BLUR;
ApplyToBackground(b =>
{
// Returns background dim and blur to the values specified by PlayerLoader.
b.EnableUserDim.Value = false;
b.BlurAmount.Value = BACKGROUND_BLUR;
});
BackgroundBrightnessReduction = true;
}

View File

@ -1,6 +1,7 @@
// 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.
using System;
using osu.Game.Screens.Backgrounds;
namespace osu.Game.Screens.Play
@ -9,6 +10,6 @@ namespace osu.Game.Screens.Play
{
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
public new BackgroundScreenBeatmap Background => (BackgroundScreenBeatmap)base.Background;
public void ApplyToBackground(Action<BackgroundScreenBeatmap> action) => base.ApplyToBackground(b => action.Invoke((BackgroundScreenBeatmap)b));
}
}

View File

@ -18,14 +18,13 @@ using osu.Game.Input.Bindings;
using osu.Game.Online.API;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking.Statistics;
using osuTK;
namespace osu.Game.Screens.Ranking
{
public abstract class ResultsScreen : OsuScreen, IKeyBindingHandler<GlobalAction>
public abstract class ResultsScreen : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>
{
protected const float BACKGROUND_BLUR = 20;
private static readonly float screen_height = 768 - TwoLayerButton.SIZE_EXTENDED.Y;
@ -35,8 +34,6 @@ namespace osu.Game.Screens.Ranking
// Temporary for now to stop dual transitions. Should respect the current toolbar mode, but there's no way to do so currently.
public override bool HideOverlaysOnEnter => true;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
public readonly Bindable<ScoreInfo> SelectedScore = new Bindable<ScoreInfo>();
public readonly ScoreInfo Score;
@ -237,15 +234,18 @@ namespace osu.Game.Screens.Ranking
{
base.OnEntering(last);
((BackgroundScreenBeatmap)Background).BlurAmount.Value = BACKGROUND_BLUR;
ApplyToBackground(b =>
{
b.BlurAmount.Value = BACKGROUND_BLUR;
b.FadeTo(0.5f, 250);
});
Background.FadeTo(0.5f, 250);
bottomPanel.FadeTo(1, 250);
}
public override bool OnExiting(IScreen next)
{
Background.FadeTo(1, 250);
ApplyToBackground(b => b.FadeTo(1, 250));
return base.OnExiting(next);
}
@ -295,7 +295,7 @@ namespace osu.Game.Screens.Ranking
ScorePanelList.HandleInput = false;
// Dim background.
Background.FadeTo(0.1f, 150);
ApplyToBackground(b => b.FadeTo(0.1f, 150));
detachedPanel = expandedPanel;
}
@ -319,7 +319,7 @@ namespace osu.Game.Screens.Ranking
ScorePanelList.HandleInput = true;
// Un-dim background.
Background.FadeTo(0.5f, 150);
ApplyToBackground(b => b.FadeTo(0.5f, 150));
detachedPanel = null;
}

View File

@ -19,7 +19,6 @@ using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Select.Options;
@ -38,10 +37,11 @@ using osu.Game.Collections;
using osu.Game.Graphics.UserInterface;
using osu.Game.Scoring;
using System.Diagnostics;
using osu.Game.Screens.Play;
namespace osu.Game.Screens.Select
{
public abstract class SongSelect : OsuScreen, IKeyBindingHandler<GlobalAction>
public abstract class SongSelect : ScreenWithBeatmapBackground, IKeyBindingHandler<GlobalAction>
{
public static readonly float WEDGE_HEIGHT = 245;
@ -76,8 +76,6 @@ namespace osu.Game.Screens.Select
[Resolved]
private Bindable<IReadOnlyList<Mod>> selectedMods { get; set; }
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
protected BeatmapCarousel Carousel { get; private set; }
private BeatmapInfoWedge beatmapInfoWedge;
@ -689,12 +687,12 @@ namespace osu.Game.Screens.Select
/// <param name="beatmap">The working beatmap.</param>
private void updateComponentFromBeatmap(WorkingBeatmap beatmap)
{
if (Background is BackgroundScreenBeatmap backgroundModeBeatmap)
ApplyToBackground(backgroundModeBeatmap =>
{
backgroundModeBeatmap.Beatmap = beatmap;
backgroundModeBeatmap.BlurAmount.Value = BACKGROUND_BLUR;
backgroundModeBeatmap.FadeColour(Color4.White, 250);
}
});
beatmapInfoWedge.Beatmap = beatmap;