2022-04-26 16:31:55 +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.
using osu.Framework.Allocation ;
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Colour ;
2022-05-22 02:49:29 +08:00
using osu.Framework.Graphics.Containers ;
2022-04-26 16:31:55 +08:00
using osu.Framework.Graphics.Shapes ;
using osu.Framework.Input.Events ;
using osu.Framework.Localisation ;
using osu.Game.Graphics.Containers ;
using osu.Game.Graphics.Sprites ;
using osu.Game.Overlays ;
using osuTK ;
namespace osu.Game.Graphics.UserInterface
{
2022-11-24 13:32:20 +08:00
public partial class ShearedButton : OsuClickableContainer
2022-04-26 16:31:55 +08:00
{
2024-05-16 09:49:33 +08:00
public const float DEFAULT_HEIGHT = 50 ;
2023-09-11 14:29:37 +08:00
public const float CORNER_RADIUS = 7 ;
public const float BORDER_THICKNESS = 2 ;
2022-04-26 16:31:55 +08:00
public LocalisableString Text
{
get = > text . Text ;
set = > text . Text = value ;
}
2022-04-26 17:14:57 +08:00
public float TextSize
{
get = > text . Font . Size ;
set = > text . Font = OsuFont . TorusAlternate . With ( size : value ) ;
}
2022-04-26 16:31:55 +08:00
public Colour4 DarkerColour
{
set
{
darkerColour = value ;
Scheduler . AddOnce ( updateState ) ;
}
}
public Colour4 LighterColour
{
set
{
lighterColour = value ;
Scheduler . AddOnce ( updateState ) ;
}
}
public Colour4 TextColour
{
set
{
textColour = value ;
Scheduler . AddOnce ( updateState ) ;
}
}
[Resolved]
protected OverlayColourProvider ColourProvider { get ; private set ; } = null ! ;
private readonly Box background ;
private readonly OsuSpriteText text ;
2024-05-16 12:27:54 +08:00
private const float shear = OsuGame . SHEAR ;
2022-04-26 16:31:55 +08:00
private Colour4 ? darkerColour ;
private Colour4 ? lighterColour ;
private Colour4 ? textColour ;
2022-05-22 02:49:29 +08:00
private readonly Container backgroundLayer ;
2022-04-26 17:03:34 +08:00
private readonly Box flashLayer ;
2024-05-16 10:01:49 +08:00
protected readonly Container ButtonContent ;
2022-04-26 16:31:55 +08:00
/// <summary>
/// Creates a new <see cref="ShearedToggleButton"/>
/// </summary>
/// <param name="width">
/// The width of the button.
/// <list type="bullet">
/// <item>If a non-<see langword="null"/> value is provided, this button will have a fixed width equal to the provided value.</item>
/// <item>If a <see langword="null"/> value is provided (or the argument is omitted entirely), the button will autosize in width to fit the text.</item>
/// </list>
/// </param>
2024-05-16 09:49:33 +08:00
/// <param name="height">The height of the button.</param>
public ShearedButton ( float? width = null , float height = DEFAULT_HEIGHT )
2022-04-26 16:31:55 +08:00
{
2024-05-16 09:49:33 +08:00
Height = height ;
Padding = new MarginPadding { Horizontal = shear * height } ;
2022-04-26 16:31:55 +08:00
2023-09-11 14:29:37 +08:00
Content . CornerRadius = CORNER_RADIUS ;
2022-04-26 16:31:55 +08:00
Content . Shear = new Vector2 ( shear , 0 ) ;
Content . Masking = true ;
Content . Anchor = Content . Origin = Anchor . Centre ;
Children = new Drawable [ ]
{
2022-05-22 02:49:29 +08:00
backgroundLayer = new Container
2022-04-26 16:31:55 +08:00
{
2022-07-23 03:40:24 +08:00
RelativeSizeAxes = Axes . Y ,
2023-09-11 14:29:37 +08:00
CornerRadius = CORNER_RADIUS ,
2022-05-22 02:49:29 +08:00
Masking = true ,
2023-09-11 14:29:37 +08:00
BorderThickness = BORDER_THICKNESS ,
2022-05-22 02:49:29 +08:00
Children = new Drawable [ ]
{
background = new Box
{
RelativeSizeAxes = Axes . Both
} ,
2024-05-16 10:01:49 +08:00
ButtonContent = new Container
2022-05-22 02:49:29 +08:00
{
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2024-05-16 10:01:49 +08:00
AutoSizeAxes = Axes . Both ,
Shear = new Vector2 ( - shear , 0 ) ,
Child = text = new OsuSpriteText
{
Font = OsuFont . TorusAlternate . With ( size : 17 ) ,
}
2022-05-22 02:49:29 +08:00
} ,
}
2022-04-26 17:03:34 +08:00
} ,
flashLayer = new Box
{
RelativeSizeAxes = Axes . Both ,
Colour = Colour4 . White . Opacity ( 0.9f ) ,
Blending = BlendingParameters . Additive ,
Alpha = 0 ,
} ,
2022-04-26 16:31:55 +08:00
} ;
if ( width ! = null )
{
Width = width . Value ;
2022-07-23 03:40:24 +08:00
backgroundLayer . RelativeSizeAxes = Axes . Both ;
2022-04-26 16:31:55 +08:00
}
else
{
AutoSizeAxes = Axes . X ;
2022-07-23 03:40:24 +08:00
backgroundLayer . AutoSizeAxes = Axes . X ;
2022-04-26 16:31:55 +08:00
text . Margin = new MarginPadding { Horizontal = 15 } ;
}
}
2022-11-03 16:44:54 +08:00
protected override HoverSounds CreateHoverSounds ( HoverSampleSet sampleSet ) = > new HoverClickSounds ( sampleSet ) { Enabled = { BindTarget = Enabled } } ;
2022-04-26 16:31:55 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
Enabled . BindValueChanged ( _ = > Scheduler . AddOnce ( updateState ) ) ;
updateState ( ) ;
FinishTransforms ( true ) ;
}
2022-04-26 17:03:34 +08:00
protected override bool OnClick ( ClickEvent e )
{
if ( Enabled . Value )
flashLayer . FadeOutFromOne ( 800 , Easing . OutQuint ) ;
return base . OnClick ( e ) ;
}
2022-04-26 16:31:55 +08:00
protected override bool OnHover ( HoverEvent e )
{
Scheduler . AddOnce ( updateState ) ;
return base . OnHover ( e ) ;
}
protected override void OnHoverLost ( HoverLostEvent e )
{
Scheduler . AddOnce ( updateState ) ;
base . OnHoverLost ( e ) ;
}
protected override bool OnMouseDown ( MouseDownEvent e )
{
2022-05-02 19:30:36 +08:00
Content . ScaleTo ( 0.9f , 2000 , Easing . OutQuint ) ;
2022-04-26 16:31:55 +08:00
return base . OnMouseDown ( e ) ;
}
protected override void OnMouseUp ( MouseUpEvent e )
{
Content . ScaleTo ( 1 , 1000 , Easing . OutElastic ) ;
base . OnMouseUp ( e ) ;
}
private void updateState ( )
{
var colourDark = darkerColour ? ? ColourProvider . Background3 ;
var colourLight = lighterColour ? ? ColourProvider . Background1 ;
2024-05-16 10:01:49 +08:00
var colourContent = textColour ? ? ColourProvider . Content1 ;
2022-04-26 16:31:55 +08:00
if ( ! Enabled . Value )
{
2022-05-02 19:30:03 +08:00
colourDark = colourDark . Darken ( 1f ) ;
colourLight = colourLight . Darken ( 1f ) ;
2022-04-26 16:31:55 +08:00
}
else if ( IsHovered )
{
2022-04-26 17:11:03 +08:00
colourDark = colourDark . Lighten ( 0.2f ) ;
colourLight = colourLight . Lighten ( 0.2f ) ;
2022-04-26 16:31:55 +08:00
}
background . FadeColour ( colourDark , 150 , Easing . OutQuint ) ;
2022-05-22 02:49:29 +08:00
backgroundLayer . TransformTo ( nameof ( BorderColour ) , ColourInfo . GradientVertical ( colourDark , colourLight ) , 150 , Easing . OutQuint ) ;
2022-04-26 16:31:55 +08:00
if ( ! Enabled . Value )
2024-05-16 10:01:49 +08:00
colourContent = colourContent . Opacity ( 0.6f ) ;
2022-04-26 16:31:55 +08:00
2024-05-16 10:01:49 +08:00
ButtonContent . FadeColour ( colourContent , 150 , Easing . OutQuint ) ;
2022-04-26 16:31:55 +08:00
}
}
}