mirror of
https://github.com/osukey/osukey.git
synced 2025-05-29 17:37:23 +09:00
Merge pull request #15190 from peppy/fix-password-popover-focus
Fix focus returning to the lounge search textbox while password is being checked
This commit is contained in:
commit
8dc91809a3
167
osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs
Normal file
167
osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
// 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 System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneDrawableLoungeRoom : OsuManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
private readonly Room room = new Room
|
||||||
|
{
|
||||||
|
HasPassword = { Value = true }
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
|
||||||
|
|
||||||
|
private DrawableLoungeRoom drawableRoom;
|
||||||
|
private SearchTextBox searchTextBox;
|
||||||
|
|
||||||
|
private readonly ManualResetEventSlim allowResponseCallback = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
var mockLounge = new Mock<LoungeSubScreen>();
|
||||||
|
mockLounge
|
||||||
|
.Setup(l => l.Join(It.IsAny<Room>(), It.IsAny<string>(), It.IsAny<Action<Room>>(), It.IsAny<Action<string>>()))
|
||||||
|
.Callback<Room, string, Action<Room>, Action<string>>((a, b, c, d) =>
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
allowResponseCallback.Wait();
|
||||||
|
allowResponseCallback.Reset();
|
||||||
|
Schedule(() => d?.Invoke("Incorrect password"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Dependencies.CacheAs(mockLounge.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("create drawable", () =>
|
||||||
|
{
|
||||||
|
Child = new PopoverContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
searchTextBox = new SearchTextBox
|
||||||
|
{
|
||||||
|
HoldFocus = true,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Margin = new MarginPadding(50),
|
||||||
|
Width = 500,
|
||||||
|
Depth = float.MaxValue
|
||||||
|
},
|
||||||
|
drawableRoom = new DrawableLoungeRoom(room)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusViaKeyboardCommit()
|
||||||
|
{
|
||||||
|
DrawableLoungeRoom.PasswordEntryPopover popover = null;
|
||||||
|
|
||||||
|
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
AddStep("click room twice", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(drawableRoom);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().SingleOrDefault()) != null);
|
||||||
|
|
||||||
|
AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("enter password", () => popover.ChildrenOfType<OsuPasswordTextBox>().Single().Text = "password");
|
||||||
|
AddStep("commit via enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddAssert("popover has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("attempt another enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddAssert("popover still has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("unblock response", () => allowResponseCallback.Set());
|
||||||
|
|
||||||
|
AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
AddStep("press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
|
AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusViaMouseCommit()
|
||||||
|
{
|
||||||
|
DrawableLoungeRoom.PasswordEntryPopover popover = null;
|
||||||
|
|
||||||
|
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
AddStep("click room twice", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(drawableRoom);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddUntilStep("wait for popover", () => (popover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().SingleOrDefault()) != null);
|
||||||
|
|
||||||
|
AddAssert("textbox has focus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("enter password", () => popover.ChildrenOfType<OsuPasswordTextBox>().Single().Text = "password");
|
||||||
|
|
||||||
|
AddStep("commit via click button", () =>
|
||||||
|
{
|
||||||
|
var button = popover.ChildrenOfType<OsuButton>().Single();
|
||||||
|
InputManager.MoveMouseTo(button);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("popover has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("attempt another click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
|
||||||
|
AddAssert("popover still has focus", () => checkFocus(popover));
|
||||||
|
|
||||||
|
AddStep("unblock response", () => allowResponseCallback.Set());
|
||||||
|
|
||||||
|
AddUntilStep("wait for textbox refocus", () => checkFocus(popover.ChildrenOfType<OsuPasswordTextBox>().Single()));
|
||||||
|
|
||||||
|
AddStep("click away", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(searchTextBox);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("search textbox has focus", () => checkFocus(searchTextBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool checkFocus(Drawable expected) =>
|
||||||
|
InputManager.FocusedDrawable == expected;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
@ -25,12 +26,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public new void Setup() => Schedule(() =>
|
public new void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Child = container = new RoomsContainer
|
Child = new PopoverContainer
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Width = 0.5f,
|
Width = 0.5f,
|
||||||
SelectedRoom = { BindTarget = SelectedRoom }
|
|
||||||
|
Child = container = new RoomsContainer
|
||||||
|
{
|
||||||
|
SelectedRoom = { BindTarget = SelectedRoom }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
|
|
||||||
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
public IEnumerable<string> FilterTerms => new[] { Room.Name.Value };
|
||||||
|
|
||||||
private bool matchingFilter;
|
private bool matchingFilter = true;
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
@ -181,6 +181,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private LoungeSubScreen lounge { get; set; }
|
private LoungeSubScreen lounge { get; set; }
|
||||||
|
|
||||||
|
public override bool HandleNonPositionalInput => true;
|
||||||
|
|
||||||
|
protected override bool BlockNonPositionalInput => true;
|
||||||
|
|
||||||
public PasswordEntryPopover(Room room)
|
public PasswordEntryPopover(Room room)
|
||||||
{
|
{
|
||||||
this.room = room;
|
this.room = room;
|
||||||
@ -200,6 +204,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
Spacing = new Vector2(5),
|
Spacing = new Vector2(5),
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
|
LayoutDuration = 500,
|
||||||
|
LayoutEasing = Easing.OutQuint,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
@ -230,10 +236,24 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
|
|
||||||
sampleJoinFail = audio.Samples.Get(@"UI/password-fail");
|
sampleJoinFail = audio.Samples.Get(@"UI/password-fail");
|
||||||
|
|
||||||
joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
joinButton.Action = performJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void joinFailed(string error)
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
|
||||||
|
passwordTextbox.OnCommit += (_, __) => performJoin();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performJoin()
|
||||||
|
{
|
||||||
|
lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
||||||
|
GetContainingInputManager().TriggerFocusContention(passwordTextbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinFailed(string error) => Schedule(() =>
|
||||||
{
|
{
|
||||||
passwordTextbox.Text = string.Empty;
|
passwordTextbox.Text = string.Empty;
|
||||||
|
|
||||||
@ -249,15 +269,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
Body.Shake();
|
Body.Shake();
|
||||||
|
|
||||||
sampleJoinFail?.Play();
|
sampleJoinFail?.Play();
|
||||||
}
|
});
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
|
|
||||||
passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
|
|||||||
popoverContainer.HidePopover();
|
popoverContainer.HidePopover();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
|
public virtual void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
|
||||||
{
|
{
|
||||||
if (joiningRoomOperation != null)
|
if (joiningRoomOperation != null)
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user