2021-05-14 15:01:17 +00: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 07:37:17 +00:00
#nullable disable
2021-05-14 15:01:17 +00:00
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
using osu.Framework.Extensions.Color4Extensions ;
using osu.Framework.Graphics ;
2022-12-20 19:36:27 +00:00
using osu.Framework.Graphics.Containers ;
2021-05-14 15:01:17 +00:00
using osu.Framework.Graphics.Effects ;
2022-12-20 19:36:27 +00:00
using osu.Framework.Graphics.Shapes ;
2021-05-15 01:24:08 +00:00
using osu.Framework.Graphics.UserInterface ;
2021-05-14 15:01:17 +00:00
using osu.Framework.Input.Events ;
2021-06-25 17:10:04 +00:00
using osu.Framework.Localisation ;
2021-05-14 15:01:17 +00:00
using osu.Game.Graphics ;
2022-12-20 19:36:27 +00:00
using osu.Game.Graphics.Containers ;
2021-05-24 11:34:47 +00:00
using osu.Game.Graphics.UserInterface ;
2021-10-15 19:44:56 +00:00
using osuTK ;
2021-05-14 15:01:17 +00:00
namespace osu.Game.Overlays
{
2022-12-20 19:36:27 +00:00
public partial class RestoreDefaultValueButton < T > : OsuClickableContainer , IHasCurrentValue < T >
2021-05-14 15:01:17 +00:00
{
public override bool IsPresent = > base . IsPresent | | Scheduler . HasPendingTasks ;
2021-05-26 09:03:15 +00:00
// this is done to ensure a click on this button doesn't trigger focus on a parent element which contains the button.
public override bool AcceptsFocus = > true ;
2021-07-08 21:39:09 +00:00
// this is intentionally not using BindableWithCurrent, as it can use the wrong IsDefault implementation when passed a BindableNumber.
// using GetBoundCopy() ensures that the received bindable is of the exact same type as the source bindable and uses the proper IsDefault implementation.
2021-07-02 19:30:26 +00:00
private Bindable < T > current ;
2021-05-15 01:24:08 +00:00
public Bindable < T > Current
2021-05-14 15:01:17 +00:00
{
2021-07-02 19:30:26 +00:00
get = > current ;
set
{
2021-07-02 20:24:51 +00:00
current ? . UnbindAll ( ) ;
current = value . GetBoundCopy ( ) ;
2021-07-02 19:30:26 +00:00
2021-07-08 21:48:48 +00:00
current . ValueChanged + = _ = > UpdateState ( ) ;
current . DefaultChanged + = _ = > UpdateState ( ) ;
current . DisabledChanged + = _ = > UpdateState ( ) ;
2021-08-16 09:40:34 +00:00
if ( IsLoaded )
UpdateState ( ) ;
2021-07-02 19:30:26 +00:00
}
2021-05-14 15:01:17 +00:00
}
2021-10-15 19:44:56 +00:00
[Resolved]
private OsuColour colours { get ; set ; }
2021-05-14 15:01:17 +00:00
2021-10-15 19:44:56 +00:00
private const float size = 4 ;
2021-05-14 15:01:17 +00:00
2022-12-20 19:36:27 +00:00
private CircularContainer circle = null ! ;
private Box background = null ! ;
public RestoreDefaultValueButton ( )
: base ( HoverSampleSet . Button )
{
}
2021-05-14 15:01:17 +00:00
[BackgroundDependencyLoader]
private void load ( OsuColour colour )
{
2022-12-20 19:36:27 +00:00
// size intentionally much larger than actual drawn content, so that the button is easier to click.
2021-10-15 19:44:56 +00:00
Size = new Vector2 ( 3 * size ) ;
2022-12-20 19:36:27 +00:00
Add ( circle = new CircularContainer
{
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
Size = new Vector2 ( size ) ,
Masking = true ,
Child = background = new Box
{
RelativeSizeAxes = Axes . Both ,
Colour = colour . Lime1
}
} ) ;
2021-05-24 11:34:47 +00:00
Alpha = 0f ;
2021-05-24 12:08:34 +00:00
Action + = ( ) = >
{
2021-07-02 19:30:26 +00:00
if ( ! current . Disabled )
current . SetDefault ( ) ;
2021-05-24 12:08:34 +00:00
} ;
2021-05-14 15:01:17 +00:00
}
2021-07-10 14:57:52 +00:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2021-10-15 19:44:56 +00:00
updateState ( ) ;
FinishTransforms ( true ) ;
2021-07-10 14:57:52 +00:00
}
2022-12-20 19:36:27 +00:00
public override LocalisableString TooltipText = > "revert to default" ;
2021-05-14 15:01:17 +00:00
protected override bool OnHover ( HoverEvent e )
{
UpdateState ( ) ;
return false ;
}
protected override void OnHoverLost ( HoverLostEvent e )
{
UpdateState ( ) ;
}
public void UpdateState ( ) = > Scheduler . AddOnce ( updateState ) ;
2021-10-15 19:44:56 +00:00
private const double fade_duration = 200 ;
2021-08-16 09:40:34 +00:00
2021-05-14 15:01:17 +00:00
private void updateState ( )
{
2021-07-02 18:06:57 +00:00
if ( current = = null )
2021-05-14 15:01:17 +00:00
return ;
2021-10-15 19:44:56 +00:00
Enabled . Value = ! Current . Disabled ;
if ( ! Current . Disabled )
{
this . FadeTo ( Current . IsDefault ? 0 : 1 , fade_duration , Easing . OutQuint ) ;
2022-12-20 19:36:27 +00:00
background . FadeColour ( IsHovered ? colours . Lime0 : colours . Lime1 , fade_duration , Easing . OutQuint ) ;
circle . TweenEdgeEffectTo ( new EdgeEffectParameters
2021-10-15 19:44:56 +00:00
{
Colour = ( IsHovered ? colours . Lime1 : colours . Lime3 ) . Opacity ( 0.4f ) ,
Radius = IsHovered ? 8 : 4 ,
Type = EdgeEffectType . Glow
} , fade_duration , Easing . OutQuint ) ;
}
else
{
2022-12-20 19:36:27 +00:00
background . FadeColour ( colours . Lime3 , fade_duration , Easing . OutQuint ) ;
circle . TweenEdgeEffectTo ( new EdgeEffectParameters
2021-10-15 19:44:56 +00:00
{
2021-10-18 17:43:48 +00:00
Colour = colours . Lime3 . Opacity ( 0.1f ) ,
2021-10-15 19:44:56 +00:00
Radius = 2 ,
Type = EdgeEffectType . Glow
} , fade_duration , Easing . OutQuint ) ;
}
2021-05-14 15:01:17 +00:00
}
}
2021-05-17 18:44:47 +00:00
}