mirror of
https://github.com/ppy/osu.git
synced 2026-05-22 19:41:06 +08:00
Add ability for LoadingLayer to block all keyboard input
This commit is contained in:
@@ -7,21 +7,27 @@ using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.UserInterface
|
||||
{
|
||||
public partial class TestSceneLoadingLayer : OsuTestScene
|
||||
public partial class TestSceneLoadingLayer : OsuManualInputManagerTestScene
|
||||
{
|
||||
private TestLoadingLayer overlay;
|
||||
|
||||
private Container content;
|
||||
|
||||
private PressableButton pressableButton;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
@@ -51,10 +57,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
{
|
||||
new OsuSpriteText { Text = "Sample content" },
|
||||
new RoundedButton { Text = "can't puush me", Width = 200, },
|
||||
new RoundedButton { Text = "puush me", Width = 200, Action = () => { } },
|
||||
pressableButton = new PressableButton { Text = "puush me", Width = 200 },
|
||||
}
|
||||
},
|
||||
overlay = new TestLoadingLayer(true),
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -63,20 +68,62 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
[Test]
|
||||
public void TestShowHide()
|
||||
{
|
||||
AddStep("create loading layer", () => content.Add(overlay = new TestLoadingLayer(true)));
|
||||
|
||||
AddAssert("not visible", () => !overlay.IsPresent);
|
||||
|
||||
AddStep("show", () => overlay.Show());
|
||||
|
||||
AddUntilStep("wait for content dim", () => overlay.Alpha > 0);
|
||||
|
||||
AddStep("hide", () => overlay.Hide());
|
||||
|
||||
AddUntilStep("wait for content restore", () => Precision.AlmostEquals(overlay.Alpha, 0));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBlockPositional(bool blockInput)
|
||||
{
|
||||
AddStep("create loading layer", () => content.Add(overlay = new TestLoadingLayer(true) { BlockPositionalInput = blockInput }));
|
||||
AddStep("show", () => overlay.Show());
|
||||
|
||||
AddStep("click button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(pressableButton);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddAssert("check pressed", () => pressableButton.Pressed, () => Is.EqualTo(!blockInput));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBlockNonPositional(bool blockKeyboardInput)
|
||||
{
|
||||
AddStep("create loading layer", () => content.Add(overlay = new TestLoadingLayer(true) { BlockNonPositionalInput = blockKeyboardInput }));
|
||||
AddStep("show", () => overlay.Show());
|
||||
|
||||
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||
|
||||
AddAssert("check pressed", () => pressableButton.Pressed, () => Is.EqualTo(!blockKeyboardInput));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBlockNonPositionalGlobalAction(bool blockKeyboardInput)
|
||||
{
|
||||
AddStep("create loading layer", () => content.Add(overlay = new TestLoadingLayer(true) { BlockNonPositionalInput = blockKeyboardInput }));
|
||||
AddStep("show", () => overlay.Show());
|
||||
|
||||
AddStep("press enter", () => InputManager.Key(Key.F8));
|
||||
|
||||
AddAssert("check pressed", () => pressableButton.Pressed, () => Is.EqualTo(!blockKeyboardInput));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLargeArea()
|
||||
{
|
||||
AddStep("create loading layer", () => content.Add(overlay = new TestLoadingLayer(true)));
|
||||
|
||||
AddStep("show", () =>
|
||||
{
|
||||
content.RelativeSizeAxes = Axes.Both;
|
||||
@@ -88,6 +135,42 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
AddStep("hide", () => overlay.Hide());
|
||||
}
|
||||
|
||||
public partial class PressableButton : RoundedButton, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
public PressableButton()
|
||||
{
|
||||
Action = () => Pressed = true;
|
||||
}
|
||||
|
||||
public bool Pressed { get; private set; }
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
if (e.Key == Key.Enter)
|
||||
{
|
||||
Pressed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
||||
{
|
||||
if (e.Action == GlobalAction.ToggleChat)
|
||||
{
|
||||
Pressed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private partial class TestLoadingLayer : LoadingLayer
|
||||
{
|
||||
public TestLoadingLayer(bool dimBackground = false, bool withBox = true)
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@@ -17,20 +19,28 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// Also optionally dims target elements.
|
||||
/// Useful for disabling all elements in a form and showing we are waiting on a response, for instance.
|
||||
/// </summary>
|
||||
public partial class LoadingLayer : LoadingSpinner
|
||||
public partial class LoadingLayer : LoadingSpinner, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
private readonly bool blockInput;
|
||||
/// <summary>
|
||||
/// Whether to block positional input of components behind the loading layer.
|
||||
/// Defaults to <c>true</c>.
|
||||
/// </summary>
|
||||
public bool BlockPositionalInput { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to block all keyboard input. Includes global actions.
|
||||
/// Defaults to <c>false</c>.
|
||||
/// </summary>
|
||||
public bool BlockNonPositionalInput { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new loading spinner.
|
||||
/// </summary>
|
||||
/// <param name="dimBackground">Whether the full background area should be dimmed while loading.</param>
|
||||
/// <param name="withBox">Whether the spinner should have a surrounding black box for visibility.</param>
|
||||
/// <param name="blockInput">Whether to block input of components behind the loading layer.</param>
|
||||
public LoadingLayer(bool dimBackground = false, bool withBox = true, bool blockInput = true)
|
||||
public LoadingLayer(bool dimBackground = false, bool withBox = true)
|
||||
: base(withBox)
|
||||
{
|
||||
this.blockInput = blockInput;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = new Vector2(1);
|
||||
|
||||
@@ -48,11 +58,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandleNonPositionalInput => false;
|
||||
public override bool HandleNonPositionalInput => BlockNonPositionalInput;
|
||||
|
||||
protected override bool Handle(UIEvent e)
|
||||
{
|
||||
if (!blockInput)
|
||||
if (!BlockPositionalInput)
|
||||
return false;
|
||||
|
||||
switch (e)
|
||||
@@ -76,5 +86,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
MainContents.Size = new Vector2(Math.Clamp(Math.Min(DrawWidth, DrawHeight) * 0.25f, 20, 80));
|
||||
}
|
||||
|
||||
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e) => BlockNonPositionalInput;
|
||||
|
||||
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,9 @@ namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
spinner = new LoadingLayer(dimBackground: true, withBox: false, blockInput: false)
|
||||
spinner = new LoadingLayer(dimBackground: true, withBox: false)
|
||||
{
|
||||
BlockPositionalInput = false,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
@@ -114,7 +114,10 @@ namespace osu.Game.Screens.Play
|
||||
Anchor = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
},
|
||||
loading = new LoadingLayer(dimBackground: true, blockInput: false)
|
||||
loading = new LoadingLayer(dimBackground: true)
|
||||
{
|
||||
BlockPositionalInput = false,
|
||||
}
|
||||
}
|
||||
},
|
||||
versionFlow = new FillFlowContainer
|
||||
|
||||
Reference in New Issue
Block a user