2019-07-15 02:48:33 +00:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2019-01-24 08:43:03 +00:00
// See the LICENCE file in the repository root for full licence text.
2018-04-13 09:19:50 +00:00
2019-07-12 02:50:06 +00:00
using System ;
2019-03-12 08:32:40 +00:00
using System.Threading ;
2018-04-13 09:19:50 +00:00
using osu.Framework.Allocation ;
2019-02-22 11:44:02 +00:00
using osu.Framework.Bindables ;
2018-04-13 09:19:50 +00:00
using osu.Framework.Graphics ;
using osu.Game.Beatmaps ;
2019-07-12 02:50:06 +00:00
using osu.Game.Configuration ;
2018-04-13 09:19:50 +00:00
using osu.Game.Graphics.Backgrounds ;
2019-02-20 07:53:57 +00:00
using osu.Game.Graphics.Containers ;
2019-07-12 02:50:06 +00:00
using osu.Game.Screens.Play ;
using osuTK ;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Screens.Backgrounds
{
2019-03-14 07:09:17 +00:00
public class BackgroundScreenBeatmap : BackgroundScreen
2018-04-13 09:19:50 +00:00
{
2019-07-12 04:44:43 +00:00
/// <summary>
/// The amount of blur to apply when full user blur is requested.
/// </summary>
public const float USER_BLUR_FACTOR = 25 ;
2019-03-20 05:17:35 +00:00
protected Background Background ;
2019-02-15 07:57:53 +00:00
private WorkingBeatmap beatmap ;
2019-02-24 11:03:24 +00:00
/// <summary>
2021-04-15 05:02:12 +00:00
/// Whether or not user-configured settings relating to brightness of elements should be ignored
2019-02-24 11:03:24 +00:00
/// </summary>
2021-04-15 05:02:12 +00:00
public readonly Bindable < bool > IgnoreUserSettings = new Bindable < bool > ( ) ;
2019-02-24 11:03:24 +00:00
2019-02-28 09:25:58 +00:00
public readonly Bindable < bool > StoryboardReplacesBackground = new Bindable < bool > ( ) ;
2019-02-15 07:17:01 +00:00
2019-03-20 05:17:35 +00:00
/// <summary>
/// The amount of blur to be applied in addition to user-specified blur.
/// </summary>
2020-02-01 21:50:29 +00:00
public readonly Bindable < float > BlurAmount = new BindableFloat ( ) ;
2019-03-14 05:02:46 +00:00
2019-12-10 12:13:44 +00:00
internal readonly IBindable < bool > IsBreakTime = new Bindable < bool > ( ) ;
2019-07-12 02:50:06 +00:00
private readonly DimmableBackground dimmable ;
2019-02-24 11:03:24 +00:00
2019-07-12 02:50:06 +00:00
protected virtual DimmableBackground CreateFadeContainer ( ) = > new DimmableBackground { RelativeSizeAxes = Axes . Both } ;
2019-02-15 07:17:01 +00:00
2019-03-12 03:56:01 +00:00
public BackgroundScreenBeatmap ( WorkingBeatmap beatmap = null )
{
Beatmap = beatmap ;
2019-07-12 02:50:06 +00:00
InternalChild = dimmable = CreateFadeContainer ( ) ;
2020-01-09 04:43:57 +00:00
2021-04-15 05:02:12 +00:00
// Beatmap background screens should not apply user settings by default.
IgnoreUserSettings . Value = true ;
dimmable . IgnoreUserSettings . BindTo ( IgnoreUserSettings ) ;
2019-12-10 12:13:44 +00:00
dimmable . IsBreakTime . BindTo ( IsBreakTime ) ;
2019-07-12 02:50:06 +00:00
dimmable . BlurAmount . BindTo ( BlurAmount ) ;
2020-01-09 04:43:57 +00:00
StoryboardReplacesBackground . BindTo ( dimmable . StoryboardReplacesBackground ) ;
2019-03-12 03:56:01 +00:00
}
[BackgroundDependencyLoader]
private void load ( )
{
2019-03-12 08:32:40 +00:00
var background = new BeatmapBackground ( beatmap ) ;
LoadComponent ( background ) ;
switchBackground ( background ) ;
2019-03-12 03:56:01 +00:00
}
2019-03-12 08:32:40 +00:00
private CancellationTokenSource cancellationSource ;
2019-03-12 05:01:27 +00:00
public WorkingBeatmap Beatmap
2018-04-13 09:19:50 +00:00
{
2019-02-28 04:58:19 +00:00
get = > beatmap ;
2018-04-13 09:19:50 +00:00
set
{
if ( beatmap = = value & & beatmap ! = null )
return ;
beatmap = value ;
Schedule ( ( ) = >
{
2019-11-25 09:28:43 +00:00
if ( ( Background as BeatmapBackground ) ? . Beatmap . BeatmapInfo . BackgroundEquals ( beatmap ? . BeatmapInfo ) ? ? false )
2019-03-12 08:32:40 +00:00
return ;
2019-03-12 03:55:54 +00:00
2019-03-12 08:32:40 +00:00
cancellationSource ? . Cancel ( ) ;
LoadComponentAsync ( new BeatmapBackground ( beatmap ) , switchBackground , ( cancellationSource = new CancellationTokenSource ( ) ) . Token ) ;
2018-04-13 09:19:50 +00:00
} ) ;
}
}
2019-03-12 08:32:40 +00:00
private void switchBackground ( BeatmapBackground b )
2018-04-13 09:19:50 +00:00
{
2019-03-11 15:05:05 +00:00
float newDepth = 0 ;
2019-04-01 03:16:05 +00:00
2019-03-11 15:05:05 +00:00
if ( Background ! = null )
{
newDepth = Background . Depth + 1 ;
Background . FinishTransforms ( ) ;
Background . FadeOut ( 250 ) ;
Background . Expire ( ) ;
}
b . Depth = newDepth ;
2019-07-12 02:50:06 +00:00
dimmable . Background = Background = b ;
2019-02-15 07:17:01 +00:00
}
2018-04-13 09:19:50 +00:00
public override bool Equals ( BackgroundScreen other )
{
2019-03-12 08:32:40 +00:00
if ( ! ( other is BackgroundScreenBeatmap otherBeatmapBackground ) ) return false ;
2018-04-13 09:19:50 +00:00
return base . Equals ( other ) & & beatmap = = otherBeatmapBackground . Beatmap ;
}
2019-07-12 02:50:06 +00:00
public class DimmableBackground : UserDimContainer
{
/// <summary>
/// The amount of blur to be applied to the background in addition to user-specified blur.
/// </summary>
/// <remarks>
/// Used in contexts where there can potentially be both user and screen-specified blurring occuring at the same time, such as in <see cref="PlayerLoader"/>
/// </remarks>
2020-02-01 21:50:29 +00:00
public readonly Bindable < float > BlurAmount = new BindableFloat ( ) ;
2019-07-12 02:50:06 +00:00
public Background Background
{
get = > background ;
set
{
2019-07-12 04:45:34 +00:00
background ? . Expire ( ) ;
2019-07-12 02:50:06 +00:00
base . Add ( background = value ) ;
background . BlurTo ( blurTarget , 0 , Easing . OutQuint ) ;
}
}
private Bindable < double > userBlurLevel { get ; set ; }
private Background background ;
public override void Add ( Drawable drawable )
{
if ( drawable is Background )
throw new InvalidOperationException ( $"Use {nameof(Background)} to set a background." ) ;
base . Add ( drawable ) ;
}
/// <summary>
/// As an optimisation, we add the two blur portions to be applied rather than actually applying two separate blurs.
/// </summary>
2021-04-15 05:02:12 +00:00
private Vector2 blurTarget = > ! IgnoreUserSettings . Value
2019-07-12 04:44:43 +00:00
? new Vector2 ( BlurAmount . Value + ( float ) userBlurLevel . Value * USER_BLUR_FACTOR )
2019-07-12 02:50:06 +00:00
: new Vector2 ( BlurAmount . Value ) ;
[BackgroundDependencyLoader]
private void load ( OsuConfigManager config )
{
userBlurLevel = config . GetBindable < double > ( OsuSetting . BlurLevel ) ;
2019-07-15 02:48:33 +00:00
}
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2019-07-12 02:50:06 +00:00
userBlurLevel . ValueChanged + = _ = > UpdateVisuals ( ) ;
BlurAmount . ValueChanged + = _ = > UpdateVisuals ( ) ;
}
2021-04-13 06:25:08 +00:00
protected override bool ShowDimContent
2021-04-15 05:02:12 +00:00
// The background needs to be hidden in the case of it being replaced by the storyboard
= > ( ! ShowStoryboard . Value & & ! IgnoreUserSettings . Value ) | | ! StoryboardReplacesBackground . Value ;
2019-07-12 02:50:06 +00:00
protected override void UpdateVisuals ( )
{
base . UpdateVisuals ( ) ;
Background ? . BlurTo ( blurTarget , BACKGROUND_FADE_DURATION , Easing . OutQuint ) ;
}
}
2018-04-13 09:19:50 +00:00
}
}