Skip to content

Commit

Permalink
Merge pull request #28509 from bdach/slider-anchor-type-switching
Browse files Browse the repository at this point in the history
Add ability to cycle slider control point types via keyboard
  • Loading branch information
peppy authored Jul 4, 2024
2 parents 73d71d3 + e151454 commit 3f13848
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Visual;
using osuTK;
using osuTK.Input;

namespace osu.Game.Rulesets.Osu.Tests.Editor
{
Expand Down Expand Up @@ -177,6 +178,79 @@ public void TestStackingUpdatesPointsPosition()
addAssertPointPositionChanged(points, i);
}

[Test]
public void TestChangingControlPointTypeViaTab()
{
createVisualiser(true);

addControlPointStep(new Vector2(200), PathType.LINEAR);
addControlPointStep(new Vector2(300));
addControlPointStep(new Vector2(500, 300));
addControlPointStep(new Vector2(700, 200));
addControlPointStep(new Vector2(500, 100));

AddStep("select first control point", () => visualiser.Pieces[0].IsSelected.Value = true);
AddStep("press tab", () => InputManager.Key(Key.Tab));
assertControlPointPathType(0, PathType.BEZIER);

AddStep("press shift-tab", () =>
{
InputManager.PressKey(Key.LShift);
InputManager.Key(Key.Tab);
InputManager.ReleaseKey(Key.LShift);
});
assertControlPointPathType(0, PathType.LINEAR);

AddStep("press shift-tab", () =>
{
InputManager.PressKey(Key.LShift);
InputManager.Key(Key.Tab);
InputManager.ReleaseKey(Key.LShift);
});
assertControlPointPathType(0, PathType.BSpline(4));

AddStep("press shift-tab", () =>
{
InputManager.PressKey(Key.LShift);
InputManager.Key(Key.Tab);
InputManager.ReleaseKey(Key.LShift);
});
assertControlPointPathType(0, PathType.PERFECT_CURVE);
assertControlPointPathType(2, PathType.BSpline(4));

AddStep("select third last control point", () =>
{
visualiser.Pieces[0].IsSelected.Value = false;
visualiser.Pieces[2].IsSelected.Value = true;
});

AddStep("press shift-tab", () =>
{
InputManager.PressKey(Key.LShift);
InputManager.Key(Key.Tab);
InputManager.ReleaseKey(Key.LShift);
});
assertControlPointPathType(2, PathType.PERFECT_CURVE);

AddRepeatStep("press tab", () => InputManager.Key(Key.Tab), 2);
assertControlPointPathType(0, PathType.BEZIER);
assertControlPointPathType(2, null);

AddStep("select first and third control points", () =>
{
visualiser.Pieces[0].IsSelected.Value = true;
visualiser.Pieces[2].IsSelected.Value = true;
});
AddStep("press alt-1", () =>
{
InputManager.PressKey(Key.AltLeft);
InputManager.Key(Key.Number1);
InputManager.ReleaseKey(Key.AltLeft);
});
assertControlPointPathType(0, PathType.LINEAR);
assertControlPointPathType(2, PathType.LINEAR);
}

private void addAssertPointPositionChanged(Vector2[] points, int index)
{
AddAssert($"Point at {points.ElementAt(index)} changed",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Tests.Visual;
Expand Down Expand Up @@ -57,7 +60,7 @@ public void TestPlaceWithMouseMovement()
assertPlaced(true);
assertLength(200);
assertControlPointCount(2);
assertControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(0, PathType.LINEAR);
}

[Test]
Expand All @@ -71,7 +74,7 @@ public void TestPlaceWithMouseMovementOutsidePlayfield()

assertPlaced(true);
assertControlPointCount(2);
assertControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(0, PathType.LINEAR);
}

[Test]
Expand All @@ -89,7 +92,7 @@ public void TestPlaceNormalControlPoint()
assertPlaced(true);
assertControlPointCount(3);
assertControlPointPosition(1, new Vector2(100, 0));
assertControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
}

[Test]
Expand All @@ -111,7 +114,7 @@ public void TestPlaceTwoNormalControlPoints()
assertControlPointCount(4);
assertControlPointPosition(1, new Vector2(100, 0));
assertControlPointPosition(2, new Vector2(100, 100));
assertControlPointType(0, PathType.BEZIER);
assertFinalControlPointType(0, PathType.BEZIER);
}

[Test]
Expand All @@ -130,8 +133,8 @@ public void TestPlaceSegmentControlPoint()
assertPlaced(true);
assertControlPointCount(3);
assertControlPointPosition(1, new Vector2(100, 0));
assertControlPointType(0, PathType.LINEAR);
assertControlPointType(1, PathType.LINEAR);
assertFinalControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(1, PathType.LINEAR);
}

[Test]
Expand All @@ -149,7 +152,7 @@ public void TestMoveToPerfectCurveThenPlaceLinear()

assertPlaced(true);
assertControlPointCount(2);
assertControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(0, PathType.LINEAR);
assertLength(100);
}

Expand All @@ -171,7 +174,7 @@ public void TestMoveToBezierThenPlacePerfectCurve()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
}

[Test]
Expand All @@ -195,7 +198,7 @@ public void TestMoveToFourthOrderBezierThenPlaceThirdOrderBezier()

assertPlaced(true);
assertControlPointCount(4);
assertControlPointType(0, PathType.BEZIER);
assertFinalControlPointType(0, PathType.BEZIER);
}

[Test]
Expand All @@ -215,8 +218,8 @@ public void TestPlaceLinearSegmentThenPlaceLinearSegment()
assertControlPointCount(3);
assertControlPointPosition(1, new Vector2(100, 0));
assertControlPointPosition(2, new Vector2(100));
assertControlPointType(0, PathType.LINEAR);
assertControlPointType(1, PathType.LINEAR);
assertFinalControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(1, PathType.LINEAR);
}

[Test]
Expand All @@ -239,8 +242,8 @@ public void TestPlaceLinearSegmentThenPlacePerfectCurveSegment()
assertControlPointCount(4);
assertControlPointPosition(1, new Vector2(100, 0));
assertControlPointPosition(2, new Vector2(100));
assertControlPointType(0, PathType.LINEAR);
assertControlPointType(1, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.LINEAR);
assertFinalControlPointType(1, PathType.PERFECT_CURVE);
}

[Test]
Expand Down Expand Up @@ -268,8 +271,46 @@ public void TestPlacePerfectCurveSegmentThenPlacePerfectCurveSegment()
assertControlPointPosition(2, new Vector2(100));
assertControlPointPosition(3, new Vector2(200, 100));
assertControlPointPosition(4, new Vector2(200));
assertControlPointType(0, PathType.PERFECT_CURVE);
assertControlPointType(2, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(2, PathType.PERFECT_CURVE);
}

[Test]
public void TestManualPathTypeControlViaKeyboard()
{
addMovementStep(new Vector2(200));
addClickStep(MouseButton.Left);

addMovementStep(new Vector2(300, 200));
addClickStep(MouseButton.Left);

addMovementStep(new Vector2(300));

assertControlPointTypeDuringPlacement(0, PathType.PERFECT_CURVE);

AddRepeatStep("press tab", () => InputManager.Key(Key.Tab), 2);
assertControlPointTypeDuringPlacement(0, PathType.LINEAR);

AddStep("press shift-tab", () =>
{
InputManager.PressKey(Key.ShiftLeft);
InputManager.Key(Key.Tab);
InputManager.ReleaseKey(Key.ShiftLeft);
});
assertControlPointTypeDuringPlacement(0, PathType.BSpline(4));

AddStep("start new segment via S", () => InputManager.Key(Key.S));
assertControlPointTypeDuringPlacement(2, PathType.LINEAR);

addMovementStep(new Vector2(400, 300));
addClickStep(MouseButton.Left);

addMovementStep(new Vector2(400));
addClickStep(MouseButton.Right);

assertPlaced(true);
assertFinalControlPointType(0, PathType.BSpline(4));
assertFinalControlPointType(2, PathType.PERFECT_CURVE);
}

[Test]
Expand All @@ -293,7 +334,7 @@ public void TestSliderDrawingDoesntActivateAfterNormalPlacement()
addClickStep(MouseButton.Right);
assertPlaced(true);

assertControlPointType(0, PathType.BEZIER);
assertFinalControlPointType(0, PathType.BEZIER);
}

[Test]
Expand All @@ -312,11 +353,11 @@ public void TestSliderDrawingCurve()
assertPlaced(true);
assertLength(808, tolerance: 10);
assertControlPointCount(5);
assertControlPointType(0, PathType.BSpline(4));
assertControlPointType(1, null);
assertControlPointType(2, null);
assertControlPointType(3, null);
assertControlPointType(4, null);
assertFinalControlPointType(0, PathType.BSpline(4));
assertFinalControlPointType(1, null);
assertFinalControlPointType(2, null);
assertFinalControlPointType(3, null);
assertFinalControlPointType(4, null);
}

[Test]
Expand All @@ -337,10 +378,10 @@ public void TestSliderDrawingLinear()
assertPlaced(true);
assertLength(600, tolerance: 10);
assertControlPointCount(4);
assertControlPointType(0, PathType.BSpline(4));
assertControlPointType(1, PathType.BSpline(4));
assertControlPointType(2, PathType.BSpline(4));
assertControlPointType(3, null);
assertFinalControlPointType(0, PathType.BSpline(4));
assertFinalControlPointType(1, PathType.BSpline(4));
assertFinalControlPointType(2, PathType.BSpline(4));
assertFinalControlPointType(3, null);
}

[Test]
Expand All @@ -359,7 +400,7 @@ public void TestPlacePerfectCurveSegmentAlmostLinearlyExterior()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.BEZIER);
assertFinalControlPointType(0, PathType.BEZIER);
}

[Test]
Expand All @@ -379,7 +420,7 @@ public void TestPlacePerfectCurveSegmentRecovery()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
}

[Test]
Expand All @@ -400,7 +441,7 @@ public void TestPlacePerfectCurveSegmentLarge()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
}

[Test]
Expand All @@ -421,7 +462,7 @@ public void TestPlacePerfectCurveSegmentTooLarge()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.BEZIER);
assertFinalControlPointType(0, PathType.BEZIER);
}

[Test]
Expand All @@ -438,7 +479,7 @@ public void TestPlacePerfectCurveSegmentCompleteArc()

assertPlaced(true);
assertControlPointCount(3);
assertControlPointType(0, PathType.PERFECT_CURVE);
assertFinalControlPointType(0, PathType.PERFECT_CURVE);
}

private void addMovementStep(Vector2 position) => AddStep($"move mouse to {position}", () => InputManager.MoveMouseTo(InputManager.ToScreenSpace(position)));
Expand All @@ -454,7 +495,10 @@ private void addClickStep(MouseButton button)

private void assertControlPointCount(int expected) => AddAssert($"has {expected} control points", () => getSlider()!.Path.ControlPoints.Count, () => Is.EqualTo(expected));

private void assertControlPointType(int index, PathType? type) => AddAssert($"control point {index} is {type?.ToString() ?? "inherit"}", () => getSlider()!.Path.ControlPoints[index].Type, () => Is.EqualTo(type));
private void assertControlPointTypeDuringPlacement(int index, PathType? type) => AddAssert($"control point {index} is {type?.ToString() ?? "inherit"}",
() => this.ChildrenOfType<PathControlPointPiece<Slider>>().ElementAt(index).ControlPoint.Type, () => Is.EqualTo(type));

private void assertFinalControlPointType(int index, PathType? type) => AddAssert($"control point {index} is {type?.ToString() ?? "inherit"}", () => getSlider()!.Path.ControlPoints[index].Type, () => Is.EqualTo(type));

private void assertControlPointPosition(int index, Vector2 position) =>
AddAssert($"control point {index} at {position}", () => Precision.AlmostEquals(position, getSlider()!.Path.ControlPoints[index].Position, 1));
Expand Down
Loading

0 comments on commit 3f13848

Please sign in to comment.