2021-05-15 01:01:17 +10: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.
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
2023-01-16 19:37:47 +03:00
using osu.Framework.Extensions.LocalisationExtensions ;
2023-07-13 14:26:01 +09:00
using osu.Framework.Extensions.ObjectExtensions ;
2021-05-15 01:01:17 +10:00
using osu.Framework.Graphics ;
2022-12-20 20:36:27 +01:00
using osu.Framework.Graphics.Shapes ;
2023-07-13 14:26:01 +09:00
using osu.Framework.Graphics.Sprites ;
2021-05-15 11:24:08 +10:00
using osu.Framework.Graphics.UserInterface ;
2021-05-15 01:01:17 +10:00
using osu.Framework.Input.Events ;
2021-06-25 19:10:04 +02:00
using osu.Framework.Localisation ;
2023-07-13 21:45:06 +02:00
using osu.Game.Graphics ;
2022-12-20 20:36:27 +01:00
using osu.Game.Graphics.Containers ;
2023-01-16 19:37:47 +03:00
using osu.Game.Localisation ;
2023-07-13 14:26:01 +09:00
using osuTK ;
2021-05-15 01:01:17 +10:00
namespace osu.Game.Overlays
{
2023-07-13 13:46:50 +09:00
public partial class RevertToDefaultButton < T > : OsuClickableContainer , IHasCurrentValue < T >
2021-05-15 01:01:17 +10:00
{
public override bool IsPresent = > base . IsPresent | | Scheduler . HasPendingTasks ;
2021-05-26 18:03:15 +09: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-09 00:39:09 +03: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.
2023-07-13 14:26:01 +09:00
private Bindable < T > ? current ;
private SpriteIcon icon = null ! ;
private Circle circle = null ! ;
[Resolved]
2023-07-13 21:45:06 +02:00
private OsuColour colours { get ; set ; } = null ! ;
[Resolved]
private OverlayColourProvider ? colourProvider { get ; set ; }
2021-07-02 22:30:26 +03:00
2021-05-15 11:24:08 +10:00
public Bindable < T > Current
2021-05-15 01:01:17 +10:00
{
2023-07-13 14:26:01 +09:00
get = > current . AsNonNull ( ) ;
2021-07-02 22:30:26 +03:00
set
{
2021-07-02 23:24:51 +03:00
current ? . UnbindAll ( ) ;
current = value . GetBoundCopy ( ) ;
2021-07-02 22:30:26 +03:00
2021-07-09 00:48:48 +03:00
current . ValueChanged + = _ = > UpdateState ( ) ;
current . DefaultChanged + = _ = > UpdateState ( ) ;
current . DisabledChanged + = _ = > UpdateState ( ) ;
2021-08-16 18:40:34 +09:00
if ( IsLoaded )
UpdateState ( ) ;
2021-07-02 22:30:26 +03:00
}
2021-05-15 01:01:17 +10:00
}
[BackgroundDependencyLoader]
2023-07-13 14:26:01 +09:00
private void load ( )
2021-05-15 01:01:17 +10:00
{
2023-07-13 14:26:01 +09:00
Size = new Vector2 ( 14 ) ;
2021-10-15 21:44:56 +02:00
2023-07-13 14:26:01 +09:00
AddRange ( new Drawable [ ]
2022-12-20 20:36:27 +01:00
{
2023-07-13 14:26:01 +09:00
circle = new Circle
2022-12-20 20:36:27 +01:00
{
2023-07-13 14:26:01 +09:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2022-12-20 20:36:27 +01:00
RelativeSizeAxes = Axes . Both ,
2023-07-13 14:26:01 +09:00
} ,
icon = new SpriteIcon
{
Icon = FontAwesome . Solid . Undo ,
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
Size = new Vector2 ( 8 ) ,
2022-12-20 20:36:27 +01:00
}
} ) ;
2021-05-24 21:34:47 +10:00
2021-05-24 22:08:34 +10:00
Action + = ( ) = >
{
2023-07-13 14:26:01 +09:00
if ( current ? . Disabled = = false )
2021-07-02 22:30:26 +03:00
current . SetDefault ( ) ;
2021-05-24 22:08:34 +10:00
} ;
2021-05-15 01:01:17 +10:00
}
2021-07-10 17:57:52 +03:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2024-07-08 15:50:27 +09:00
2021-10-15 21:44:56 +02:00
updateState ( ) ;
FinishTransforms ( true ) ;
2021-07-10 17:57:52 +03:00
}
2023-01-16 19:37:47 +03:00
public override LocalisableString TooltipText = > CommonStrings . RevertToDefault . ToLower ( ) ;
2021-05-15 01:01:17 +10:00
protected override bool OnHover ( HoverEvent e )
{
2024-07-08 15:50:27 +09:00
updateHover ( ) ;
2021-05-15 01:01:17 +10:00
return false ;
}
protected override void OnHoverLost ( HoverLostEvent e )
{
2024-07-08 15:50:27 +09:00
updateHover ( ) ;
2021-05-15 01:01:17 +10:00
}
public void UpdateState ( ) = > Scheduler . AddOnce ( updateState ) ;
2021-10-15 21:44:56 +02:00
private const double fade_duration = 200 ;
2021-08-16 18:40:34 +09:00
2024-07-08 15:50:27 +09:00
private bool? isDisplayed ;
2021-05-15 01:01:17 +10:00
private void updateState ( )
{
2021-07-02 21:06:57 +03:00
if ( current = = null )
2021-05-15 01:01:17 +10:00
return ;
2024-07-08 15:50:27 +09:00
// Avoid running animations if we are already in an up-to-date state.
if ( Enabled . Value = = ! current . Disabled & & isDisplayed = = ! current . IsDefault )
return ;
2023-07-13 14:26:01 +09:00
Enabled . Value = ! current . Disabled ;
2024-07-08 15:50:27 +09:00
isDisplayed = ! current . IsDefault ;
updateHover ( ) ;
2023-07-13 14:26:01 +09:00
2024-07-08 15:50:27 +09:00
if ( isDisplayed = = false )
2024-01-18 14:20:07 +03:00
this . FadeTo ( 0 , fade_duration , Easing . OutQuint ) ;
else if ( current . Disabled )
this . FadeTo ( 0.2f , fade_duration , Easing . OutQuint ) ;
else
2024-07-08 15:50:27 +09:00
{
icon . RotateTo ( 150 ) . RotateTo ( 0 , fade_duration * 2 , Easing . OutQuint ) ;
icon . ScaleTo ( 0.7f ) . ScaleTo ( 1 , fade_duration * 2 , Easing . OutQuint ) ;
2024-01-18 14:20:07 +03:00
this . FadeTo ( 1 , fade_duration , Easing . OutQuint ) ;
2024-07-08 15:50:27 +09:00
}
}
2021-10-15 21:44:56 +02:00
2024-07-08 15:50:27 +09:00
private void updateHover ( )
{
2023-07-13 14:26:01 +09:00
if ( IsHovered & & Enabled . Value )
2021-10-15 21:44:56 +02:00
{
2023-07-13 14:26:01 +09:00
icon . RotateTo ( - 40 , 500 , Easing . OutQuint ) ;
2023-07-13 21:45:06 +02:00
icon . FadeColour ( colourProvider ? . Light1 ? ? colours . YellowLight , 300 , Easing . OutQuint ) ;
circle . FadeColour ( colourProvider ? . Background2 ? ? colours . Gray6 , 300 , Easing . OutQuint ) ;
2023-07-13 14:26:01 +09:00
this . ScaleTo ( 1.2f , 300 , Easing . OutQuint ) ;
2021-10-15 21:44:56 +02:00
}
else
{
2023-07-13 14:26:01 +09:00
icon . RotateTo ( 0 , 100 , Easing . OutQuint ) ;
2023-07-13 21:45:06 +02:00
icon . FadeColour ( colourProvider ? . Colour0 ? ? colours . Yellow , 100 , Easing . OutQuint ) ;
circle . FadeColour ( colourProvider ? . Background3 ? ? colours . Gray3 , 100 , Easing . OutQuint ) ;
2023-07-13 14:26:01 +09:00
this . ScaleTo ( 1f , 100 , Easing . OutQuint ) ;
2021-10-15 21:44:56 +02:00
}
2021-05-15 01:01:17 +10:00
}
}
2021-05-17 20:44:47 +02:00
}