Skip to content

Commit 717b1b1

Browse files
committed
Add warning display when player loading is paused due to user interaction
As touched on in ppy#37082. 15 minute task fixing a UX which was definitely not as visible as it should have been.
1 parent 98debc8 commit 717b1b1

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

osu.Game/Screens/Play/BeatmapMetadataDisplay.cs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using osu.Framework.Bindables;
99
using osu.Framework.Graphics;
1010
using osu.Framework.Graphics.Containers;
11+
using osu.Framework.Graphics.Shapes;
1112
using osu.Framework.Graphics.Sprites;
1213
using osu.Framework.Localisation;
1314
using osu.Game.Beatmaps;
@@ -19,6 +20,7 @@
1920
using osu.Game.Rulesets.Mods;
2021
using osu.Game.Screens.Play.HUD;
2122
using osuTK;
23+
using osuTK.Graphics;
2224
using CommonStrings = osu.Game.Localisation.CommonStrings;
2325

2426
namespace osu.Game.Screens.Play
@@ -32,6 +34,7 @@ public partial class BeatmapMetadataDisplay : Container
3234
private readonly Bindable<IReadOnlyList<Mod>> mods;
3335
private readonly Drawable logoFacade;
3436
private LoadingSpinner loading;
37+
private Drawable blockingLoadLayer;
3538

3639
public IBindable<IReadOnlyList<Mod>> Mods => mods;
3740

@@ -46,6 +49,30 @@ public bool Loading
4649
}
4750
}
4851

52+
private bool userBlocked;
53+
54+
public bool UserBlocked
55+
{
56+
set
57+
{
58+
if (value == userBlocked)
59+
return;
60+
61+
userBlocked = value;
62+
63+
if (userBlocked)
64+
{
65+
blockingLoadLayer
66+
.FadeIn(300, Easing.Out)
67+
.Then()
68+
.FadeTo(0.5f, 1000, Easing.In)
69+
.Loop();
70+
}
71+
else
72+
blockingLoadLayer.FadeOut(500, Easing.OutQuint);
73+
}
74+
}
75+
4976
public BeatmapMetadataDisplay(IWorkingBeatmap beatmap, Bindable<IReadOnlyList<Mod>> mods, Drawable logoFacade)
5077
{
5178
this.beatmap = beatmap;
@@ -61,7 +88,7 @@ public BeatmapMetadataDisplay(IWorkingBeatmap beatmap, Bindable<IReadOnlyList<Mo
6188
private StarRatingDisplay starRatingDisplay;
6289

6390
[BackgroundDependencyLoader]
64-
private void load(BeatmapDifficultyCache difficultyCache)
91+
private void load(BeatmapDifficultyCache difficultyCache, OsuColour colours)
6592
{
6693
var metadata = beatmap.BeatmapInfo.Metadata;
6794

@@ -117,7 +144,28 @@ private void load(BeatmapDifficultyCache difficultyCache)
117144
loading = new LoadingLayer(dimBackground: true)
118145
{
119146
BlockPositionalInput = false,
120-
}
147+
},
148+
blockingLoadLayer = new Container
149+
{
150+
RelativeSizeAxes = Axes.Both,
151+
Alpha = 0,
152+
Children = new Drawable[]
153+
{
154+
new Box
155+
{
156+
Colour = colours.PinkDarker,
157+
Alpha = 0.5f,
158+
RelativeSizeAxes = Axes.Both,
159+
},
160+
new OsuSpriteText
161+
{
162+
Anchor = Anchor.Centre,
163+
Origin = Anchor.Centre,
164+
Font = OsuFont.Style.Heading2,
165+
Text = "Loading paused.."
166+
}
167+
}
168+
},
121169
}
122170
},
123171
versionFlow = new FillFlowContainer

osu.Game/Screens/Play/PlayerLoader.cs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,7 @@ protected bool BackgroundBrightnessReduction
120120
}
121121
}
122122

123-
private bool readyForPush =>
124-
!playerConsumed
125-
// don't push unless the player is completely loaded
126-
&& CurrentPlayer?.LoadState == LoadState.Ready
127-
// don't push unless the player is ready to start gameplay
128-
&& ReadyForGameplay;
129-
130-
protected virtual bool ReadyForGameplay =>
131-
// not ready if the user is hovering one of the panes (logo is excluded), unless they are idle.
132-
(IsHovered || osuLogo?.IsHovered == true || idleTracker.IsIdle.Value)
133-
// not ready if the user is dragging a slider or otherwise.
134-
&& (inputManager.DraggedDrawable == null || inputManager.DraggedDrawable is OsuLogo)
135-
// not ready if a focused overlay is visible, like settings.
136-
&& inputManager.FocusedDrawable is not OsuFocusedOverlayContainer
137-
// or if a child of a focused overlay is focused, like settings' search textbox.
138-
&& inputManager.FocusedDrawable?.FindClosestParent<OsuFocusedOverlayContainer>() == null;
123+
protected virtual bool ReadyForGameplay { get; private set; }
139124

140125
private bool holdForMenuExitButton => !AllowUserExit;
141126

@@ -490,6 +475,18 @@ protected override void Update()
490475
if (!this.IsCurrentScreen())
491476
return;
492477

478+
ReadyForGameplay =
479+
// not ready if the user is hovering one of the panes (logo is excluded), unless they are idle.
480+
(IsHovered || osuLogo?.IsHovered == true || idleTracker.IsIdle.Value)
481+
// not ready if the user is dragging a slider or otherwise.
482+
&& (inputManager.DraggedDrawable == null || inputManager.DraggedDrawable is OsuLogo)
483+
// not ready if a focused overlay is visible, like settings.
484+
&& inputManager.FocusedDrawable is not OsuFocusedOverlayContainer
485+
// or if a child of a focused overlay is focused, like settings' search textbox.
486+
&& inputManager.FocusedDrawable?.FindClosestParent<OsuFocusedOverlayContainer>() == null;
487+
488+
MetadataInfo.UserBlocked = !ReadyForGameplay && CurrentPlayer?.LoadState == LoadState.Ready;
489+
493490
// We need to perform this check here rather than in OnHover as any number of children of VisualSettings
494491
// may also be handling the hover events.
495492
if (inputManager.HoveredDrawables.Contains(VisualSettings) || QuickRestart)
@@ -654,6 +651,13 @@ private void pushWhenLoaded()
654651

655652
if (!this.IsCurrentScreen()) return;
656653

654+
bool readyForPush =
655+
!playerConsumed
656+
// don't push unless the player is completely loaded
657+
&& CurrentPlayer?.LoadState == LoadState.Ready
658+
// don't push unless the player is ready to start gameplay
659+
&& ReadyForGameplay;
660+
657661
if (!readyForPush)
658662
{
659663
// as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce

0 commit comments

Comments
 (0)