1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-16 08:37:24 +08:00
osu-lazer/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

269 lines
11 KiB
C#
Raw Normal View History

// 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.
2022-06-17 15:37:17 +08:00
#nullable disable
using System;
2021-04-24 14:35:02 +08:00
using System.Linq;
using JetBrains.Annotations;
2021-04-24 14:35:02 +08:00
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2024-01-20 08:13:05 +08:00
using osu.Framework.Graphics.Primitives;
2021-04-24 14:35:02 +08:00
using osu.Framework.Testing;
using osu.Framework.Threading;
using osu.Game.Screens.Edit.Compose.Components;
2024-01-20 08:13:05 +08:00
using osu.Game.Utils;
using osuTK;
2021-04-24 14:35:02 +08:00
using osuTK.Input;
namespace osu.Game.Tests.Visual.Editing
{
2021-04-24 14:35:02 +08:00
public partial class TestSceneComposeSelectBox : OsuManualInputManagerTestScene
{
2020-09-29 18:19:48 +08:00
private Container selectionArea;
2021-04-24 14:35:02 +08:00
private SelectionBox selectionBox;
2020-09-29 18:19:48 +08:00
[Cached(typeof(SelectionRotationHandler))]
private TestSelectionRotationHandler rotationHandler;
2024-01-20 08:13:05 +08:00
[Cached(typeof(SelectionScaleHandler))]
private TestSelectionScaleHandler scaleHandler;
public TestSceneComposeSelectBox()
{
rotationHandler = new TestSelectionRotationHandler(() => selectionArea);
2024-01-20 08:13:05 +08:00
scaleHandler = new TestSelectionScaleHandler(() => selectionArea);
}
2021-04-26 00:57:16 +08:00
[SetUp]
public void SetUp() => Schedule(() =>
{
2021-04-26 00:57:16 +08:00
Child = selectionArea = new Container
{
Size = new Vector2(400),
Position = -new Vector2(150),
Anchor = Anchor.Centre,
Children = new Drawable[]
{
2021-04-26 00:57:16 +08:00
selectionBox = new SelectionBox
{
2021-05-05 05:28:49 +08:00
RelativeSizeAxes = Axes.Both,
CanFlipX = true,
CanFlipY = true,
}
2021-04-26 00:57:16 +08:00
}
};
2021-04-26 00:57:16 +08:00
InputManager.MoveMouseTo(selectionBox);
InputManager.ReleaseButton(MouseButton.Left);
2021-04-26 00:57:16 +08:00
});
2020-09-29 18:19:48 +08:00
private partial class TestSelectionRotationHandler : SelectionRotationHandler
2020-09-29 18:19:48 +08:00
{
private readonly Func<Container> getTargetContainer;
public TestSelectionRotationHandler(Func<Container> getTargetContainer)
{
this.getTargetContainer = getTargetContainer;
2024-05-29 15:40:29 +08:00
CanRotateAroundSelectionOrigin.Value = true;
}
[CanBeNull]
private Container targetContainer;
private float? initialRotation;
public override void Begin()
{
if (targetContainer != null)
throw new InvalidOperationException($"Cannot {nameof(Begin)} a rotate operation while another is in progress!");
targetContainer = getTargetContainer();
initialRotation = targetContainer!.Rotation;
DefaultOrigin = ToLocalSpace(targetContainer.ToScreenSpace(Vector2.Zero));
2024-06-25 22:41:43 +08:00
base.Begin();
}
public override void Update(float rotation, Vector2? origin = null)
{
if (targetContainer == null)
throw new InvalidOperationException($"Cannot {nameof(Update)} a rotate operation without calling {nameof(Begin)} first!");
// kinda silly and wrong, but just showing that the drag handles work.
targetContainer.Rotation = initialRotation!.Value + rotation;
}
public override void Commit()
{
if (targetContainer == null)
throw new InvalidOperationException($"Cannot {nameof(Commit)} a rotate operation without calling {nameof(Begin)} first!");
targetContainer = null;
initialRotation = null;
2024-06-25 22:41:43 +08:00
base.Commit();
}
2020-09-29 18:19:48 +08:00
}
2021-04-24 14:35:02 +08:00
2024-01-20 08:13:05 +08:00
private partial class TestSelectionScaleHandler : SelectionScaleHandler
{
private readonly Func<Container> getTargetContainer;
public TestSelectionScaleHandler(Func<Container> getTargetContainer)
{
this.getTargetContainer = getTargetContainer;
CanScaleX.Value = true;
CanScaleY.Value = true;
CanScaleDiagonally.Value = true;
}
[CanBeNull]
private Container targetContainer;
public override void Begin()
{
if (targetContainer != null)
throw new InvalidOperationException($"Cannot {nameof(Begin)} a scale operation while another is in progress!");
targetContainer = getTargetContainer();
OriginalSurroundingQuad = new Quad(targetContainer!.X, targetContainer.Y, targetContainer.Width, targetContainer.Height);
}
2024-07-03 22:23:19 +08:00
public override void Update(Vector2 scale, Vector2? origin = null, Axes adjustAxis = Axes.Both, float axisRotation = 0)
2024-01-20 08:13:05 +08:00
{
if (targetContainer == null)
throw new InvalidOperationException($"Cannot {nameof(Update)} a scale operation without calling {nameof(Begin)} first!");
Vector2 actualOrigin = origin ?? Vector2.Zero;
targetContainer.Position = GeometryUtils.GetScaledPosition(scale, actualOrigin, OriginalSurroundingQuad!.Value.TopLeft);
targetContainer.Size = OriginalSurroundingQuad!.Value.Size * scale;
}
public override void Commit()
{
if (targetContainer == null)
throw new InvalidOperationException($"Cannot {nameof(Commit)} a scale operation without calling {nameof(Begin)} first!");
targetContainer = null;
}
}
2021-04-24 14:35:02 +08:00
[Test]
public void TestRotationHandleShownOnHover()
{
SelectionBoxRotationHandle rotationHandle = null;
AddStep("retrieve rotation handle", () => rotationHandle = this.ChildrenOfType<SelectionBoxRotationHandle>().First());
AddAssert("handle hidden", () => rotationHandle.Alpha == 0);
AddStep("hover over handle", () => InputManager.MoveMouseTo(rotationHandle));
AddUntilStep("rotation handle shown", () => rotationHandle.Alpha == 1);
AddStep("move mouse away", () => InputManager.MoveMouseTo(selectionBox));
AddUntilStep("handle hidden", () => rotationHandle.Alpha == 0);
}
[Test]
public void TestRotationHandleShownOnHoveringClosestScaleHandler()
{
SelectionBoxRotationHandle rotationHandle = null;
AddStep("retrieve rotation handle", () => rotationHandle = this.ChildrenOfType<SelectionBoxRotationHandle>().First());
AddAssert("rotation handle hidden", () => rotationHandle.Alpha == 0);
AddStep("hover over closest scale handle", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<SelectionBoxScaleHandle>().Single(s => s.Anchor == rotationHandle.Anchor));
});
AddUntilStep("rotation handle shown", () => rotationHandle.Alpha == 1);
AddStep("move mouse away", () => InputManager.MoveMouseTo(selectionBox));
AddUntilStep("handle hidden", () => rotationHandle.Alpha == 0);
}
[Test]
public void TestHoverRotationHandleFromScaleHandle()
{
SelectionBoxRotationHandle rotationHandle = null;
AddStep("retrieve rotation handle", () => rotationHandle = this.ChildrenOfType<SelectionBoxRotationHandle>().First());
AddAssert("rotation handle hidden", () => rotationHandle.Alpha == 0);
AddStep("hover over closest scale handle", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<SelectionBoxScaleHandle>().Single(s => s.Anchor == rotationHandle.Anchor));
});
AddUntilStep("rotation handle shown", () => rotationHandle.Alpha == 1);
AddAssert("rotation handle not hovered", () => !rotationHandle.IsHovered);
AddStep("hover over rotation handle", () => InputManager.MoveMouseTo(rotationHandle));
AddAssert("rotation handle still shown", () => rotationHandle.Alpha == 1);
AddAssert("rotation handle hovered", () => rotationHandle.IsHovered);
AddStep("move mouse away", () => InputManager.MoveMouseTo(selectionBox));
AddUntilStep("handle hidden", () => rotationHandle.Alpha == 0);
}
[Test]
public void TestHoldingScaleHandleHidesCorrespondingRotationHandle()
2021-04-24 14:35:02 +08:00
{
SelectionBoxRotationHandle rotationHandle = null;
AddStep("retrieve rotation handle", () => rotationHandle = this.ChildrenOfType<SelectionBoxRotationHandle>().First());
AddAssert("rotation handle hidden", () => rotationHandle.Alpha == 0);
AddStep("hover over closest scale handle", () =>
2021-04-24 14:35:02 +08:00
{
InputManager.MoveMouseTo(this.ChildrenOfType<SelectionBoxScaleHandle>().Single(s => s.Anchor == rotationHandle.Anchor));
});
AddUntilStep("rotation handle shown", () => rotationHandle.Alpha == 1);
AddStep("hold scale handle", () => InputManager.PressButton(MouseButton.Left));
AddUntilStep("rotation handle hidden", () => rotationHandle.Alpha == 0);
int i;
ScheduledDelegate mouseMove = null;
AddStep("start dragging", () =>
{
i = 0;
2021-04-24 14:35:02 +08:00
mouseMove = Scheduler.AddDelayed(() =>
{
InputManager.MoveMouseTo(selectionBox.ScreenSpaceDrawQuad.TopLeft + Vector2.One * (5 * ++i));
}, 100, true);
});
AddAssert("rotation handle still hidden", () => rotationHandle.Alpha == 0);
2021-04-24 14:35:02 +08:00
AddStep("end dragging", () => mouseMove.Cancel());
AddAssert("rotation handle still hidden", () => rotationHandle.Alpha == 0);
2021-04-24 14:35:02 +08:00
AddStep("unhold left", () => InputManager.ReleaseButton(MouseButton.Left));
AddUntilStep("rotation handle shown", () => rotationHandle.Alpha == 1);
2021-04-24 14:35:02 +08:00
AddStep("move mouse away", () => InputManager.MoveMouseTo(selectionBox, new Vector2(20)));
AddUntilStep("rotation handle hidden", () => rotationHandle.Alpha == 0);
2021-04-24 14:35:02 +08:00
}
2021-05-12 16:07:31 +08:00
/// <summary>
/// Tests that hovering over two handles instantaneously from one to another does not crash or cause issues to the visibility state.
/// </summary>
[Test]
public void TestHoverOverTwoHandlesInstantaneously()
{
AddStep("hover over top-left scale handle", () =>
InputManager.MoveMouseTo(this.ChildrenOfType<SelectionBoxScaleHandle>().Single(s => s.Anchor == Anchor.TopLeft)));
AddStep("hover over top-right scale handle", () =>
InputManager.MoveMouseTo(this.ChildrenOfType<SelectionBoxScaleHandle>().Single(s => s.Anchor == Anchor.TopRight)));
AddUntilStep("top-left rotation handle hidden", () =>
this.ChildrenOfType<SelectionBoxRotationHandle>().Single(r => r.Anchor == Anchor.TopLeft).Alpha == 0);
AddUntilStep("top-right rotation handle shown", () =>
this.ChildrenOfType<SelectionBoxRotationHandle>().Single(r => r.Anchor == Anchor.TopRight).Alpha == 1);
}
}
}