Merge branch 'master' into display-sr-changes

This commit is contained in:
Dan Balasescu 2021-09-15 10:22:11 +09:00 committed by GitHub
commit 5ea1924c30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 51 deletions

View File

@ -3,6 +3,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -82,7 +83,23 @@ public void TestPopoverHidesOnLeavingScreen()
}
[Test]
public void TestJoinRoomWithPassword()
public void TestJoinRoomWithIncorrectPassword()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "wrong");
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
AddAssert("room not joined", () => loungeScreen.IsCurrentScreen());
AddUntilStep("password prompt still visible", () => passwordEntryPopover.State.Value == Visibility.Visible);
}
[Test]
public void TestJoinRoomWithCorrectPassword()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;

View File

@ -38,6 +38,33 @@ public static ScheduledDelegate BeginKeyRepeat(this IKeyBindingHandler handler,
return repeatDelegate;
}
/// <summary>
/// Shakes this drawable.
/// </summary>
/// <param name="target">The target to shake.</param>
/// <param name="shakeDuration">The length of a single shake.</param>
/// <param name="shakeMagnitude">Pixels of displacement per shake.</param>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public static void Shake(this Drawable target, double shakeDuration = 80, float shakeMagnitude = 8, double? maximumLength = null)
{
// if we don't have enough time, don't bother shaking.
if (maximumLength < shakeDuration * 2)
return;
var sequence = target.MoveToX(shakeMagnitude, shakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= shakeDuration * 4)
{
sequence = sequence
.MoveToX(shakeMagnitude, shakeDuration, Easing.InOutSine).Then()
.MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then();
}
sequence.MoveToX(0, shakeDuration / 2, Easing.InSine);
}
/// <summary>
/// Accepts a delta vector in screen-space coordinates and converts it to one which can be applied to this drawable's position.
/// </summary>

View File

@ -1,8 +1,8 @@
// 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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Extensions;
namespace osu.Game.Graphics.Containers
{
@ -16,40 +16,10 @@ public class ShakeContainer : Container
/// </summary>
public float ShakeDuration = 80;
/// <summary>
/// Total number of shakes. May be shortened if possible.
/// </summary>
public float TotalShakes = 4;
/// <summary>
/// Pixels of displacement per shake.
/// </summary>
public float ShakeMagnitude = 8;
/// <summary>
/// Shake the contents of this container.
/// </summary>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public void Shake(double? maximumLength = null)
{
const float shake_amount = 8;
// if we don't have enough time, don't bother shaking.
if (maximumLength < ShakeDuration * 2)
return;
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
{
sequence = sequence
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
}
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
}
public void Shake(double? maximumLength = null) => this.Shake(ShakeDuration, maximumLength: maximumLength);
}
}

View File

@ -87,9 +87,10 @@ public virtual void JoinRoom(Room room, string password = null, Action<Room> onS
currentJoinRoomRequest.Failure += exception =>
{
if (!(exception is OperationCanceledException))
Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important);
onError?.Invoke(exception.ToString());
if (exception is OperationCanceledException)
return;
onError?.Invoke(exception.Message);
};
api.Queue(currentJoinRoomRequest);

View File

@ -1,7 +1,6 @@
// 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.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -15,6 +14,9 @@
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Extensions;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
@ -120,7 +122,7 @@ public bool MatchingFilter
}
}
public Popover GetPopover() => new PasswordEntryPopover(Room) { JoinRequested = lounge.Join };
public Popover GetPopover() => new PasswordEntryPopover(Room);
public MenuItem[] ContextMenuItems => new MenuItem[]
{
@ -176,7 +178,8 @@ public class PasswordEntryPopover : OsuPopover
{
private readonly Room room;
public Action<Room, string> JoinRequested;
[Resolved(canBeNull: true)]
private LoungeSubScreen lounge { get; set; }
public PasswordEntryPopover(Room room)
{
@ -184,30 +187,61 @@ public PasswordEntryPopover(Room room)
}
private OsuPasswordTextBox passwordTextbox;
private TriangleButton joinButton;
private OsuSpriteText errorText;
[BackgroundDependencyLoader]
private void load()
private void load(OsuColour colours)
{
Child = new FillFlowContainer
{
Margin = new MarginPadding(10),
Spacing = new Vector2(5),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
passwordTextbox = new OsuPasswordTextBox
new FillFlowContainer
{
Width = 200,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
passwordTextbox = new OsuPasswordTextBox
{
Width = 200,
PlaceholderText = "password",
},
joinButton = new TriangleButton
{
Width = 80,
Text = "Join Room",
}
}
},
new TriangleButton
errorText = new OsuSpriteText
{
Width = 80,
Text = "Join Room",
Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text)
}
Colour = colours.Red,
},
}
};
joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
}
private void joinFailed(string error)
{
passwordTextbox.Text = string.Empty;
errorText.Text = error;
errorText
.FadeIn()
.FlashColour(Color4.White, 200)
.Delay(1000)
.FadeOutFromOne(1000, Easing.In);
Body.Shake();
}
protected override void LoadComplete()
@ -215,7 +249,7 @@ protected override void LoadComplete()
base.LoadComplete();
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text);
passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
}
}
}

View File

@ -290,7 +290,7 @@ private void onLeaving()
popoverContainer.HidePopover();
}
public void Join(Room room, string password) => Schedule(() =>
public void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
{
if (joiningRoomOperation != null)
return;
@ -302,10 +302,12 @@ public void Join(Room room, string password) => Schedule(() =>
Open(room);
joiningRoomOperation?.Dispose();
joiningRoomOperation = null;
}, _ =>
onSuccess?.Invoke(room);
}, error =>
{
joiningRoomOperation?.Dispose();
joiningRoomOperation = null;
onFailure?.Invoke(error);
});
});