2019-10-19 18:15:31 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2019-03-19 18:04:07 +08:00
// See the LICENCE file in the repository root for full licence text.
using System ;
using osu.Framework.Allocation ;
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
using osu.Framework.Graphics.Cursor ;
using osu.Framework.Input.Bindings ;
using osu.Framework.Input.Events ;
2022-08-11 04:09:58 +08:00
using osu.Framework.Localisation ;
2019-03-19 18:04:07 +08:00
using osu.Game.Rulesets.Osu.UI.Cursor ;
2024-04-16 19:24:30 +08:00
using osu.Game.Rulesets.UI ;
2019-03-19 18:04:07 +08:00
using osu.Game.Screens.Play ;
using osuTK.Graphics ;
namespace osu.Game.Rulesets.Osu.UI
{
2022-11-24 13:32:20 +08:00
public partial class OsuResumeOverlay : ResumeOverlay
2019-03-19 18:04:07 +08:00
{
2024-04-16 19:37:12 +08:00
private Container cursorScaleContainer = null ! ;
private OsuClickToResumeCursor clickToResumeCursor = null ! ;
2019-03-19 18:04:07 +08:00
2024-04-16 19:37:12 +08:00
private OsuCursorContainer ? localCursorContainer ;
2019-03-19 18:04:07 +08:00
2024-04-16 19:37:12 +08:00
public override CursorContainer ? LocalCursor = > State . Value = = Visibility . Visible ? localCursorContainer : null ;
2019-03-19 18:04:07 +08:00
2022-08-11 04:09:58 +08:00
protected override LocalisableString Message = > "Click the orange cursor to resume" ;
2019-03-19 18:04:07 +08:00
2024-04-16 19:24:30 +08:00
[Resolved]
private DrawableRuleset ? drawableRuleset { get ; set ; }
2019-03-19 18:04:07 +08:00
[BackgroundDependencyLoader]
2019-03-25 14:30:51 +08:00
private void load ( )
2019-03-19 18:04:07 +08:00
{
2023-11-06 22:37:25 +08:00
Add ( cursorScaleContainer = new Container
2019-10-16 04:44:04 +08:00
{
Child = clickToResumeCursor = new OsuClickToResumeCursor { ResumeRequested = Resume }
} ) ;
2019-03-19 18:04:07 +08:00
}
2019-11-01 13:50:38 +08:00
protected override void PopIn ( )
2019-03-19 18:04:07 +08:00
{
2024-03-04 15:08:17 +08:00
// Can't display if the cursor is outside the window.
2024-04-16 19:24:30 +08:00
if ( GameplayCursor . LastFrameState = = Visibility . Hidden | | drawableRuleset ? . Contains ( GameplayCursor . ActiveCursor . ScreenSpaceDrawQuad . Centre ) = = false )
2024-03-04 15:08:17 +08:00
{
Resume ( ) ;
return ;
}
2019-11-01 13:50:38 +08:00
base . PopIn ( ) ;
2019-10-19 17:52:07 +08:00
GameplayCursor . ActiveCursor . Hide ( ) ;
2023-11-06 22:37:25 +08:00
cursorScaleContainer . Position = ToLocalSpace ( GameplayCursor . ActiveCursor . ScreenSpaceDrawQuad . Centre ) ;
2019-10-16 04:44:04 +08:00
clickToResumeCursor . Appear ( ) ;
2019-03-25 18:21:34 +08:00
if ( localCursorContainer = = null )
2019-10-14 16:13:36 +08:00
Add ( localCursorContainer = new OsuCursorContainer ( ) ) ;
2019-03-19 18:04:07 +08:00
}
2019-11-01 13:50:38 +08:00
protected override void PopOut ( )
2019-03-19 18:04:07 +08:00
{
2019-11-01 13:50:38 +08:00
base . PopOut ( ) ;
2019-03-25 18:21:34 +08:00
localCursorContainer ? . Expire ( ) ;
localCursorContainer = null ;
2023-05-06 22:23:00 +08:00
GameplayCursor ? . ActiveCursor . Show ( ) ;
2019-03-19 18:04:07 +08:00
}
protected override bool OnHover ( HoverEvent e ) = > true ;
2022-11-24 13:32:20 +08:00
public partial class OsuClickToResumeCursor : OsuCursor , IKeyBindingHandler < OsuAction >
2019-03-19 18:04:07 +08:00
{
public override bool HandlePositionalInput = > true ;
2024-04-16 19:37:12 +08:00
public Action ? ResumeRequested ;
private Container scaleTransitionContainer = null ! ;
2019-03-19 18:04:07 +08:00
public OsuClickToResumeCursor ( )
{
RelativePositionAxes = Axes . Both ;
}
2024-01-15 19:03:23 +08:00
protected override Container CreateCursorContent ( ) = > scaleTransitionContainer = new Container
2023-12-27 02:07:21 +08:00
{
2024-01-15 19:03:23 +08:00
RelativeSizeAxes = Axes . Both ,
Origin = Anchor . Centre ,
Anchor = Anchor . Centre ,
Child = base . CreateCursorContent ( ) ,
} ;
protected override float CalculateCursorScale ( ) = >
2023-12-27 02:07:21 +08:00
// Force minimum cursor size so it's easily clickable
2024-01-15 19:03:23 +08:00
Math . Max ( 1f , base . CalculateCursorScale ( ) ) ;
2023-12-27 02:07:21 +08:00
2019-03-19 18:04:07 +08:00
protected override bool OnHover ( HoverEvent e )
{
updateColour ( ) ;
return base . OnHover ( e ) ;
}
protected override void OnHoverLost ( HoverLostEvent e )
{
updateColour ( ) ;
base . OnHoverLost ( e ) ;
}
2021-09-16 17:26:12 +08:00
public bool OnPressed ( KeyBindingPressEvent < OsuAction > e )
2019-03-19 18:04:07 +08:00
{
2021-09-16 17:26:12 +08:00
switch ( e . Action )
2019-03-19 18:04:07 +08:00
{
case OsuAction . LeftButton :
case OsuAction . RightButton :
2023-11-06 23:28:51 +08:00
if ( ! IsHovered )
return false ;
2019-03-19 18:04:07 +08:00
2024-01-15 19:03:23 +08:00
scaleTransitionContainer . ScaleTo ( 2 , TRANSITION_TIME , Easing . OutQuint ) ;
2019-03-19 18:04:07 +08:00
2024-07-20 00:19:36 +08:00
// When resuming with a button, we do not want the osu! input manager to see this button press and include it in the score.
// To ensure that this works correctly, schedule the resume operation one frame forward, since the resume operation enables the input manager to see input events.
2024-07-19 21:52:48 +08:00
Schedule ( ( ) = > ResumeRequested ? . Invoke ( ) ) ;
2019-03-19 18:04:07 +08:00
return true ;
}
return false ;
}
2021-09-16 17:26:12 +08:00
public void OnReleased ( KeyBindingReleaseEvent < OsuAction > e )
2020-01-22 12:22:34 +08:00
{
}
2019-03-19 18:04:07 +08:00
2019-10-16 04:44:04 +08:00
public void Appear ( ) = > Schedule ( ( ) = >
2019-03-19 18:04:07 +08:00
{
updateColour ( ) ;
2024-01-15 19:03:23 +08:00
// importantly, we perform the scale transition on an underlying container rather than the whole cursor
// to prevent attempts of abuse by the scale change in the cursor's hitbox (see: https://github.com/ppy/osu/issues/26477).
scaleTransitionContainer . ScaleTo ( 4 ) . Then ( ) . ScaleTo ( 1 , 1000 , Easing . OutQuint ) ;
2019-03-19 18:04:07 +08:00
} ) ;
private void updateColour ( )
{
this . FadeColour ( IsHovered ? Color4 . White : Color4 . Orange , 400 , Easing . OutQuint ) ;
}
}
}
}