Skip to content

Commit

Permalink
Merge pull request #26303 from OliBomby/grids
Browse files Browse the repository at this point in the history
Add keybind for cycling grid type
  • Loading branch information
bdach authored Oct 16, 2024
2 parents 8ed0554 + 882df6b commit 4fa101d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 14 deletions.
99 changes: 97 additions & 2 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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;
Expand Down Expand Up @@ -129,6 +130,7 @@ public void TestGridSnapMomentaryToggle()

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)", () =>
{
Expand Down Expand Up @@ -161,7 +163,8 @@ private Vector2 uniqueSnappingPosition(PositionSnapGrid grid)
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
};
Expand All @@ -170,7 +173,7 @@ private Vector2 uniqueSnappingPosition(PositionSnapGrid grid)
[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);

Expand All @@ -189,5 +192,97 @@ private void nextGridSizeIs(int size)
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);
});
}
}
}
15 changes: 8 additions & 7 deletions osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ protected override void LoadComplete()
{
GridLinesRotation.Disabled = v.NewValue == PositionSnapGridType.Circle;

gridTypeButtons.Items[(int)v.NewValue].Select();

switch (v.NewValue)
{
case PositionSnapGridType.Square:
Expand Down Expand Up @@ -241,17 +243,16 @@ private float normalizeRotation(float rotation, float period)
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;
}

Expand Down
10 changes: 7 additions & 3 deletions osu.Game/Input/Bindings/GlobalActionContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ public static IEnumerable<GlobalAction> GetGlobalActionsFor(GlobalActionCategory
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),
Expand Down Expand Up @@ -368,8 +369,8 @@ public enum GlobalAction
[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,
Expand Down Expand Up @@ -472,6 +473,9 @@ public enum GlobalAction

[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorSeekToNextSamplePoint))]
EditorSeekToNextSamplePoint,

[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCycleGridType))]
EditorCycleGridType,
}

public enum GlobalActionCategory
Expand Down
9 changes: 7 additions & 2 deletions osu.Game/Localisation/GlobalActionKeyBindingStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,14 @@ public static class GlobalActionKeyBindingStrings
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"
Expand Down

0 comments on commit 4fa101d

Please sign in to comment.