1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 11:47:24 +08:00

Merge pull request #26303 from OliBomby/grids

Add keybind for cycling grid type
This commit is contained in:
Bartłomiej Dach 2024-10-16 13:12:23 +02:00 committed by GitHub
commit 4fa101d935
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 119 additions and 14 deletions

View File

@ -9,6 +9,7 @@ using osu.Framework.Utils;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Tests.Visual;
using osu.Game.Utils;
@ -129,6 +130,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
private void gridActive<T>(bool active) where T : PositionSnapGrid
{
AddAssert($"grid type is {typeof(T).Name}", () => this.ChildrenOfType<T>().Any());
AddStep("choose placement tool", () => InputManager.Key(Key.Number2));
AddStep("move cursor to spacing + (1, 1)", () =>
{
@ -161,7 +163,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
return grid switch
{
RectangularPositionSnapGrid rectangular => rectangular.StartPosition.Value + GeometryUtils.RotateVector(rectangular.Spacing.Value, -rectangular.GridLineRotation.Value),
TriangularPositionSnapGrid triangular => triangular.StartPosition.Value + GeometryUtils.RotateVector(new Vector2(triangular.Spacing.Value / 2, triangular.Spacing.Value / 2 * MathF.Sqrt(3)), -triangular.GridLineRotation.Value),
TriangularPositionSnapGrid triangular => triangular.StartPosition.Value + GeometryUtils.RotateVector(
new Vector2(triangular.Spacing.Value / 2, triangular.Spacing.Value / 2 * MathF.Sqrt(3)), -triangular.GridLineRotation.Value),
CircularPositionSnapGrid circular => circular.StartPosition.Value + GeometryUtils.RotateVector(new Vector2(circular.Spacing.Value, 0), -45),
_ => Vector2.Zero
};
@ -170,7 +173,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
[Test]
public void TestGridSizeToggling()
{
AddStep("enable rectangular grid", () => InputManager.Key(Key.T));
AddStep("enable rectangular grid", () => InputManager.Key(Key.Y));
AddUntilStep("rectangular grid visible", () => this.ChildrenOfType<RectangularPositionSnapGrid>().Any());
gridSizeIs(4);
@ -189,5 +192,97 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
private void gridSizeIs(int size)
=> AddAssert($"grid size is {size}", () => this.ChildrenOfType<RectangularPositionSnapGrid>().Single().Spacing.Value == new Vector2(size)
&& EditorBeatmap.BeatmapInfo.GridSize == size);
[Test]
public void TestGridTypeToggling()
{
AddStep("enable rectangular grid", () => InputManager.Key(Key.T));
AddUntilStep("rectangular grid visible", () => this.ChildrenOfType<RectangularPositionSnapGrid>().Any());
gridActive<RectangularPositionSnapGrid>(true);
nextGridTypeIs<TriangularPositionSnapGrid>();
nextGridTypeIs<CircularPositionSnapGrid>();
nextGridTypeIs<RectangularPositionSnapGrid>();
}
private void nextGridTypeIs<T>() where T : PositionSnapGrid
{
AddStep("toggle to next grid type", () =>
{
InputManager.PressKey(Key.ShiftLeft);
InputManager.Key(Key.G);
InputManager.ReleaseKey(Key.ShiftLeft);
});
gridActive<T>(true);
}
[Test]
public void TestGridPlacementTool()
{
AddStep("enable rectangular grid", () => InputManager.Key(Key.T));
AddStep("start grid placement", () => InputManager.Key(Key.Number5));
AddStep("move cursor to slider head + (1, 1)", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
InputManager.MoveMouseTo(composer.ToScreenSpace(((Slider)EditorBeatmap.HitObjects.First()).Position + new Vector2(1, 1)));
});
AddStep("left click", () => InputManager.Click(MouseButton.Left));
AddStep("move cursor to slider tail + (1, 1)", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
InputManager.MoveMouseTo(composer.ToScreenSpace(((Slider)EditorBeatmap.HitObjects.First()).EndPosition + new Vector2(1, 1)));
});
AddStep("left click", () => InputManager.Click(MouseButton.Left));
gridActive<RectangularPositionSnapGrid>(true);
AddAssert("grid position at slider head", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
return Precision.AlmostEquals(((Slider)EditorBeatmap.HitObjects.First()).Position, composer.StartPosition.Value);
});
AddAssert("grid spacing is distance to slider tail", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
return Precision.AlmostEquals(composer.Spacing.Value.X, 32.05, 0.01)
&& Precision.AlmostEquals(composer.Spacing.Value.X, composer.Spacing.Value.Y);
});
AddAssert("grid rotation points to slider tail", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
return Precision.AlmostEquals(composer.GridLineRotation.Value, 0.09, 0.01);
});
AddStep("start grid placement", () => InputManager.Key(Key.Number5));
AddStep("move cursor to slider tail + (1, 1)", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
InputManager.MoveMouseTo(composer.ToScreenSpace(((Slider)EditorBeatmap.HitObjects.First()).EndPosition + new Vector2(1, 1)));
});
AddStep("double click", () =>
{
InputManager.Click(MouseButton.Left);
InputManager.Click(MouseButton.Left);
});
AddStep("move cursor to (0, 0)", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
InputManager.MoveMouseTo(composer.ToScreenSpace(Vector2.Zero));
});
gridActive<RectangularPositionSnapGrid>(true);
AddAssert("grid position at slider tail", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
return Precision.AlmostEquals(((Slider)EditorBeatmap.HitObjects.First()).EndPosition, composer.StartPosition.Value);
});
AddAssert("grid spacing and rotation unchanged", () =>
{
var composer = Editor.ChildrenOfType<RectangularPositionSnapGrid>().Single();
return Precision.AlmostEquals(composer.Spacing.Value.X, 32.05, 0.01)
&& Precision.AlmostEquals(composer.Spacing.Value.X, composer.Spacing.Value.Y)
&& Precision.AlmostEquals(composer.GridLineRotation.Value, 0.09, 0.01);
});
}
}
}

View File

@ -213,6 +213,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{
GridLinesRotation.Disabled = v.NewValue == PositionSnapGridType.Circle;
gridTypeButtons.Items[(int)v.NewValue].Select();
switch (v.NewValue)
{
case PositionSnapGridType.Square:
@ -241,17 +243,16 @@ namespace osu.Game.Rulesets.Osu.Edit
return ((rotation + 360 + period * 0.5f) % period) - period * 0.5f;
}
private void nextGridSize()
{
Spacing.Value = Spacing.Value * 2 >= max_automatic_spacing ? Spacing.Value / 8 : Spacing.Value * 2;
}
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
switch (e.Action)
{
case GlobalAction.EditorCycleGridDisplayMode:
nextGridSize();
case GlobalAction.EditorCycleGridSpacing:
Spacing.Value = Spacing.Value * 2 >= max_automatic_spacing ? Spacing.Value / 8 : Spacing.Value * 2;
return true;
case GlobalAction.EditorCycleGridType:
GridType.Value = (PositionSnapGridType)(((int)GridType.Value + 1) % Enum.GetValues<PositionSnapGridType>().Length);
return true;
}

View File

@ -134,7 +134,8 @@ namespace osu.Game.Input.Bindings
new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.EditorCloneSelection),
new KeyBinding(new[] { InputKey.J }, GlobalAction.EditorNudgeLeft),
new KeyBinding(new[] { InputKey.K }, GlobalAction.EditorNudgeRight),
new KeyBinding(new[] { InputKey.G }, GlobalAction.EditorCycleGridDisplayMode),
new KeyBinding(new[] { InputKey.G }, GlobalAction.EditorCycleGridSpacing),
new KeyBinding(new[] { InputKey.Shift, InputKey.G }, GlobalAction.EditorCycleGridType),
new KeyBinding(new[] { InputKey.F5 }, GlobalAction.EditorTestGameplay),
new KeyBinding(new[] { InputKey.T }, GlobalAction.EditorTapForBPM),
new KeyBinding(new[] { InputKey.Control, InputKey.H }, GlobalAction.EditorFlipHorizontally),
@ -368,8 +369,8 @@ namespace osu.Game.Input.Bindings
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleChatFocus))]
ToggleChatFocus,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCycleGridDisplayMode))]
EditorCycleGridDisplayMode,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCycleGridSpacing))]
EditorCycleGridSpacing,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorTestGameplay))]
EditorTestGameplay,
@ -472,6 +473,9 @@ namespace osu.Game.Input.Bindings
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorSeekToNextSamplePoint))]
EditorSeekToNextSamplePoint,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCycleGridType))]
EditorCycleGridType,
}
public enum GlobalActionCategory

View File

@ -190,9 +190,14 @@ namespace osu.Game.Localisation
public static LocalisableString EditorCloneSelection => new TranslatableString(getKey(@"editor_clone_selection"), @"Clone selection");
/// <summary>
/// "Cycle grid display mode"
/// "Cycle grid spacing"
/// </summary>
public static LocalisableString EditorCycleGridDisplayMode => new TranslatableString(getKey(@"editor_cycle_grid_display_mode"), @"Cycle grid display mode");
public static LocalisableString EditorCycleGridSpacing => new TranslatableString(getKey(@"editor_cycle_grid_spacing"), @"Cycle grid spacing");
/// <summary>
/// "Cycle grid type"
/// </summary>
public static LocalisableString EditorCycleGridType => new TranslatableString(getKey(@"editor_cycle_grid_type"), @"Cycle grid type");
/// <summary>
/// "Test gameplay"