From d3e91024a7cb9dd52185b5f067e304ffa8df3bd9 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Thu, 8 Mar 2018 18:16:23 +0900 Subject: [PATCH 1/4] Block player enter when a drag initiates from an overlaying container --- osu.Game/Screens/Play/PlayerLoader.cs | 19 ++++++++++++++++--- .../PlayerSettings/PlayerSettingsGroup.cs | 4 ++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 2950990779..e082e3f8de 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -22,7 +23,6 @@ namespace osu.Game.Screens.Play private Player player; private BeatmapMetadataDisplay info; - private VisualSettings visualSettings; private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, }); - Add(visualSettings = new VisualSettings + Add(new VisualSettings { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -116,9 +116,22 @@ namespace osu.Game.Screens.Play logo.Delay(resuming ? 0 : 500).MoveToOffset(new Vector2(0, -0.24f), 500, Easing.InOutExpo); } + private bool weHandledMouseDown; + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + weHandledMouseDown = true; + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + weHandledMouseDown = false; + return base.OnMouseUp(state, args); + } + private void pushWhenLoaded() { - if (player.LoadState != LoadState.Ready || visualSettings.IsHovered) + if (player.LoadState != LoadState.Ready || !IsHovered || GetContainingInputManager().CurrentState.Mouse.HasAnyButtonPressed && !weHandledMouseDown) { Schedule(pushWhenLoaded); return; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 95b464154a..e0de89535e 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -133,5 +134,8 @@ namespace osu.Game.Screens.Play.PlayerSettings } protected override Container<Drawable> Content => content; + + protected override bool OnHover(InputState state) => true; + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true; } } From 94ed4ab01b3748a7df6c58925b5f68bb35278943 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Thu, 8 Mar 2018 20:28:55 +0900 Subject: [PATCH 2/4] Add debouncing to player loading Allows the mouse to temporarily exit and re-enter overlay elements without triggering a load --- osu.Game/Screens/Play/PlayerLoader.cs | 42 +++++++++++++++++---------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index e082e3f8de..b91272de75 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Screens.Backgrounds; using OpenTK; using osu.Framework.Localisation; +using osu.Framework.Threading; using osu.Game.Screens.Menu; using osu.Game.Screens.Play.PlayerSettings; @@ -51,6 +52,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, }); + Add(new VisualSettings { Anchor = Anchor.TopRight, @@ -100,7 +102,7 @@ namespace osu.Game.Screens.Play contentIn(); info.Delay(750).FadeIn(500); - this.Delay(2150).Schedule(pushWhenLoaded); + this.Delay(1800).Schedule(pushWhenLoaded); } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -129,29 +131,39 @@ namespace osu.Game.Screens.Play return base.OnMouseUp(state, args); } + private ScheduledDelegate pushDebounce; + + private bool readyForPush => player.LoadState == LoadState.Ready && IsHovered && (!GetContainingInputManager().CurrentState.Mouse.HasAnyButtonPressed || weHandledMouseDown); + private void pushWhenLoaded() { - if (player.LoadState != LoadState.Ready || !IsHovered || GetContainingInputManager().CurrentState.Mouse.HasAnyButtonPressed && !weHandledMouseDown) + Schedule(pushWhenLoaded); + + if (!readyForPush) { - Schedule(pushWhenLoaded); + pushDebounce?.Cancel(); + pushDebounce = null; return; } - contentOut(); - - this.Delay(250).Schedule(() => + if (pushDebounce == null) pushDebounce = Scheduler.AddDelayed(() => { - if (!IsCurrentScreen) return; + contentOut(); - if (!Push(player)) - Exit(); - else + this.Delay(250).Schedule(() => { - //By default, we want to load the player and never be returned to. - //Note that this may change if the player we load requested a re-run. - ValidForResume = false; - } - }); + if (!IsCurrentScreen) return; + + if (!Push(player)) + Exit(); + else + { + //By default, we want to load the player and never be returned to. + //Note that this may change if the player we load requested a re-run. + ValidForResume = false; + } + }); + }, 500); } protected override bool OnExiting(Screen next) From ef8d59591445d0f18cddb4003ab7aa5ce859cf47 Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 14 Mar 2018 11:44:19 +0900 Subject: [PATCH 3/4] Apply formatting changes --- osu.Game/Screens/Play/PlayerLoader.cs | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 3f25ef8a5e..cdb6f36a6f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -112,6 +112,7 @@ namespace osu.Game.Screens.Play } private bool weHandledMouseDown; + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { weHandledMouseDown = true; @@ -139,24 +140,25 @@ namespace osu.Game.Screens.Play return; } - if (pushDebounce == null) pushDebounce = Scheduler.AddDelayed(() => - { - contentOut(); - - this.Delay(250).Schedule(() => + if (pushDebounce == null) + pushDebounce = Scheduler.AddDelayed(() => { - if (!IsCurrentScreen) return; + contentOut(); - if (!Push(player)) - Exit(); - else + this.Delay(250).Schedule(() => { - //By default, we want to load the player and never be returned to. - //Note that this may change if the player we load requested a re-run. - ValidForResume = false; - } - }); - }, 500); + if (!IsCurrentScreen) return; + + if (!Push(player)) + Exit(); + else + { + //By default, we want to load the player and never be returned to. + //Note that this may change if the player we load requested a re-run. + ValidForResume = false; + } + }); + }, 500); } protected override bool OnExiting(Screen next) From ea649f96504a72be9ebbcc55c2f70b6dd32e563b Mon Sep 17 00:00:00 2001 From: Dean Herbert <pe@ppy.sh> Date: Wed, 14 Mar 2018 12:01:15 +0900 Subject: [PATCH 4/4] Avoid scheduling during non-current screen --- osu.Game/Screens/Play/PlayerLoader.cs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index cdb6f36a6f..31e7313c0b 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -131,16 +131,22 @@ namespace osu.Game.Screens.Play private void pushWhenLoaded() { - Schedule(pushWhenLoaded); + if (!IsCurrentScreen) return; - if (!readyForPush) + try { - pushDebounce?.Cancel(); - pushDebounce = null; - return; - } + if (!readyForPush) + { + // as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce + // if we become unready for push during the delay. + pushDebounce?.Cancel(); + pushDebounce = null; + return; + } + + if (pushDebounce != null) + return; - if (pushDebounce == null) pushDebounce = Scheduler.AddDelayed(() => { contentOut(); @@ -159,6 +165,11 @@ namespace osu.Game.Screens.Play } }); }, 500); + } + finally + { + Schedule(pushWhenLoaded); + } } protected override bool OnExiting(Screen next)