2020-02-21 14:31:40 +08:00
// 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.
2022-06-17 15:37:17 +08:00
#nullable disable
2020-02-21 14:31:40 +08:00
using System ;
2021-01-06 05:47:57 +08:00
using JetBrains.Annotations ;
2020-02-21 14:31:40 +08:00
using osu.Framework.Graphics ;
2021-01-04 21:42:39 +08:00
using osu.Framework.Graphics.Shapes ;
2020-02-21 14:31:40 +08:00
using osu.Framework.Input.Events ;
using osuTK ;
using osuTK.Graphics ;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
2020-02-21 14:35:40 +08:00
/// A layer that will show a loading spinner and completely block input to an area.
2020-02-21 14:31:40 +08:00
/// Also optionally dims target elements.
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
/// </summary>
2022-11-24 13:32:20 +08:00
public partial class LoadingLayer : LoadingSpinner
2020-02-21 14:31:40 +08:00
{
2022-08-09 14:43:13 +08:00
private readonly bool blockInput ;
2021-01-06 05:47:57 +08:00
[CanBeNull]
2021-01-06 05:40:16 +08:00
protected Box BackgroundDimLayer { get ; }
2020-02-21 14:31:40 +08:00
2020-02-21 14:35:40 +08:00
/// <summary>
2021-01-04 21:42:39 +08:00
/// Construct a new loading spinner.
2020-02-21 14:35:40 +08:00
/// </summary>
2021-01-04 21:42:39 +08:00
/// <param name="dimBackground">Whether the full background area should be dimmed while loading.</param>
2020-02-21 14:35:40 +08:00
/// <param name="withBox">Whether the spinner should have a surrounding black box for visibility.</param>
2022-08-09 14:43:13 +08:00
/// <param name="blockInput">Whether to block input of components behind the loading layer.</param>
public LoadingLayer ( bool dimBackground = false , bool withBox = true , bool blockInput = true )
2020-02-21 14:31:40 +08:00
: base ( withBox )
{
2022-08-09 14:43:13 +08:00
this . blockInput = blockInput ;
2020-02-21 14:31:40 +08:00
RelativeSizeAxes = Axes . Both ;
Size = new Vector2 ( 1 ) ;
MainContents . RelativeSizeAxes = Axes . None ;
2021-01-04 21:42:39 +08:00
if ( dimBackground )
{
2021-01-05 17:10:39 +08:00
AddInternal ( BackgroundDimLayer = new Box
2021-01-04 21:42:39 +08:00
{
Depth = float . MaxValue ,
Colour = Color4 . Black ,
Alpha = 0 ,
RelativeSizeAxes = Axes . Both ,
} ) ;
}
2020-02-21 14:31:40 +08:00
}
2020-02-21 15:31:16 +08:00
public override bool HandleNonPositionalInput = > false ;
2020-02-21 14:31:40 +08:00
protected override bool Handle ( UIEvent e )
{
2022-08-09 14:43:13 +08:00
if ( ! blockInput )
return false ;
2020-02-21 14:31:40 +08:00
switch ( e )
{
// blocking scroll can cause weird behaviour when this layer is used within a ScrollContainer.
2022-06-24 20:25:23 +08:00
case ScrollEvent :
2020-02-21 14:31:40 +08:00
return false ;
2020-10-21 22:09:39 +08:00
// blocking touch events causes the ISourcedFromTouch versions to not be fired, potentially impeding behaviour of drawables *above* the loading layer that may utilise these.
2020-10-21 23:17:23 +08:00
// note that this will not work well if touch handling elements are beneath this loading layer (something to consider for the future).
2022-06-24 20:25:23 +08:00
case TouchEvent :
2020-10-21 22:09:39 +08:00
return false ;
2020-02-21 14:31:40 +08:00
}
return true ;
}
protected override void PopIn ( )
{
2021-01-05 17:10:39 +08:00
BackgroundDimLayer ? . FadeTo ( 0.5f , TRANSITION_DURATION * 2 , Easing . OutQuint ) ;
2020-02-21 14:31:40 +08:00
base . PopIn ( ) ;
}
protected override void PopOut ( )
{
2021-01-05 17:10:39 +08:00
BackgroundDimLayer ? . FadeOut ( TRANSITION_DURATION , Easing . OutQuint ) ;
2020-02-21 14:31:40 +08:00
base . PopOut ( ) ;
}
protected override void Update ( )
{
base . Update ( ) ;
2021-01-04 21:42:39 +08:00
2022-08-09 14:34:11 +08:00
MainContents . Size = new Vector2 ( Math . Clamp ( Math . Min ( DrawWidth , DrawHeight ) * 0.25f , 20 , 100 ) ) ;
2020-02-21 14:31:40 +08:00
}
}
}