2019-07-15 10:48:33 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2019-01-24 16:43:03 +08:00
// See the LICENCE file in the repository root for full licence text.
2018-04-13 17:19:50 +08:00
2019-07-12 10:50:06 +08:00
using System ;
2019-03-12 16:32:40 +08:00
using System.Threading ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Allocation ;
2019-02-22 19:44:02 +08:00
using osu.Framework.Bindables ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
using osu.Game.Beatmaps ;
2019-07-12 10:50:06 +08:00
using osu.Game.Configuration ;
2018-04-13 17:19:50 +08:00
using osu.Game.Graphics.Backgrounds ;
2019-02-20 15:53:57 +08:00
using osu.Game.Graphics.Containers ;
2019-07-12 10:50:06 +08:00
using osu.Game.Screens.Play ;
using osuTK ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Screens.Backgrounds
{
2019-03-14 15:09:17 +08:00
public class BackgroundScreenBeatmap : BackgroundScreen
2018-04-13 17:19:50 +08:00
{
2019-07-12 12:44:43 +08: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 13:17:35 +08:00
protected Background Background ;
2019-02-15 15:57:53 +08:00
private WorkingBeatmap beatmap ;
2019-02-24 19:03:24 +08:00
/// <summary>
/// Whether or not user dim settings should be applied to this Background.
/// </summary>
2019-03-20 13:17:35 +08:00
public readonly Bindable < bool > EnableUserDim = new Bindable < bool > ( ) ;
2019-02-24 19:03:24 +08:00
2019-02-28 17:25:58 +08:00
public readonly Bindable < bool > StoryboardReplacesBackground = new Bindable < bool > ( ) ;
2019-02-15 15:17:01 +08:00
2019-03-20 13:17:35 +08:00
/// <summary>
/// The amount of blur to be applied in addition to user-specified blur.
/// </summary>
2020-02-02 05:50:29 +08:00
public readonly Bindable < float > BlurAmount = new BindableFloat ( ) ;
2019-03-14 13:02:46 +08:00
2019-12-10 20:13:44 +08:00
internal readonly IBindable < bool > IsBreakTime = new Bindable < bool > ( ) ;
2019-07-12 10:50:06 +08:00
private readonly DimmableBackground dimmable ;
2019-02-24 19:03:24 +08:00
2019-07-12 10:50:06 +08:00
protected virtual DimmableBackground CreateFadeContainer ( ) = > new DimmableBackground { RelativeSizeAxes = Axes . Both } ;
2019-02-15 15:17:01 +08:00
2019-03-12 11:56:01 +08:00
public BackgroundScreenBeatmap ( WorkingBeatmap beatmap = null )
{
Beatmap = beatmap ;
2019-07-12 10:50:06 +08:00
InternalChild = dimmable = CreateFadeContainer ( ) ;
2020-01-09 12:43:57 +08:00
2019-07-12 10:50:06 +08:00
dimmable . EnableUserDim . BindTo ( EnableUserDim ) ;
2019-12-10 20:13:44 +08:00
dimmable . IsBreakTime . BindTo ( IsBreakTime ) ;
2019-07-12 10:50:06 +08:00
dimmable . BlurAmount . BindTo ( BlurAmount ) ;
2020-01-09 12:43:57 +08:00
StoryboardReplacesBackground . BindTo ( dimmable . StoryboardReplacesBackground ) ;
2019-03-12 11:56:01 +08:00
}
[BackgroundDependencyLoader]
private void load ( )
{
2019-03-12 16:32:40 +08:00
var background = new BeatmapBackground ( beatmap ) ;
LoadComponent ( background ) ;
switchBackground ( background ) ;
2019-03-12 11:56:01 +08:00
}
2019-03-12 16:32:40 +08:00
private CancellationTokenSource cancellationSource ;
2019-03-12 13:01:27 +08:00
public WorkingBeatmap Beatmap
2018-04-13 17:19:50 +08:00
{
2019-02-28 12:58:19 +08:00
get = > beatmap ;
2018-04-13 17:19:50 +08:00
set
{
if ( beatmap = = value & & beatmap ! = null )
return ;
beatmap = value ;
Schedule ( ( ) = >
{
2019-11-25 17:28:43 +08:00
if ( ( Background as BeatmapBackground ) ? . Beatmap . BeatmapInfo . BackgroundEquals ( beatmap ? . BeatmapInfo ) ? ? false )
2019-03-12 16:32:40 +08:00
return ;
2019-03-12 11:55:54 +08:00
2019-03-12 16:32:40 +08:00
cancellationSource ? . Cancel ( ) ;
LoadComponentAsync ( new BeatmapBackground ( beatmap ) , switchBackground , ( cancellationSource = new CancellationTokenSource ( ) ) . Token ) ;
2018-04-13 17:19:50 +08:00
} ) ;
}
}
2019-03-12 16:32:40 +08:00
private void switchBackground ( BeatmapBackground b )
2018-04-13 17:19:50 +08:00
{
2019-03-11 23:05:05 +08:00
float newDepth = 0 ;
2019-04-01 11:16:05 +08:00
2019-03-11 23:05:05 +08:00
if ( Background ! = null )
{
newDepth = Background . Depth + 1 ;
Background . FinishTransforms ( ) ;
Background . FadeOut ( 250 ) ;
Background . Expire ( ) ;
}
b . Depth = newDepth ;
2019-07-12 10:50:06 +08:00
dimmable . Background = Background = b ;
2019-02-15 15:17:01 +08:00
}
2018-04-13 17:19:50 +08:00
public override bool Equals ( BackgroundScreen other )
{
2019-03-12 16:32:40 +08:00
if ( ! ( other is BackgroundScreenBeatmap otherBeatmapBackground ) ) return false ;
2018-04-13 17:19:50 +08:00
return base . Equals ( other ) & & beatmap = = otherBeatmapBackground . Beatmap ;
}
2019-07-12 10:50:06 +08: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-02 05:50:29 +08:00
public readonly Bindable < float > BlurAmount = new BindableFloat ( ) ;
2019-07-12 10:50:06 +08:00
public Background Background
{
get = > background ;
set
{
2019-07-12 12:45:34 +08:00
background ? . Expire ( ) ;
2019-07-12 10:50:06 +08: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>
private Vector2 blurTarget = > EnableUserDim . Value
2019-07-12 12:44:43 +08:00
? new Vector2 ( BlurAmount . Value + ( float ) userBlurLevel . Value * USER_BLUR_FACTOR )
2019-07-12 10:50:06 +08:00
: new Vector2 ( BlurAmount . Value ) ;
[BackgroundDependencyLoader]
private void load ( OsuConfigManager config )
{
userBlurLevel = config . GetBindable < double > ( OsuSetting . BlurLevel ) ;
2019-07-15 10:48:33 +08:00
}
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2019-07-12 10:50:06 +08:00
userBlurLevel . ValueChanged + = _ = > UpdateVisuals ( ) ;
BlurAmount . ValueChanged + = _ = > UpdateVisuals ( ) ;
}
2019-08-31 05:42:20 +08:00
protected override bool ShowDimContent = > ! ShowStoryboard . Value | | ! StoryboardReplacesBackground . Value | | ! ShowVideo . Value ; // The background needs to be hidden in the case of it being replaced by the storyboard
2019-07-12 10:50:06 +08:00
protected override void UpdateVisuals ( )
{
base . UpdateVisuals ( ) ;
Background ? . BlurTo ( blurTarget , BACKGROUND_FADE_DURATION , Easing . OutQuint ) ;
}
}
2018-04-13 17:19:50 +08:00
}
}