1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 02:32:59 +08:00

Merge pull request #23799 from peppy/beat-snap-divisor-hotkeys

Add ability to cycle beat snap divisor using hotkeys
This commit is contained in:
Bartłomiej Dach 2023-06-08 00:32:52 +02:00 committed by GitHub
commit 93b1f18772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 15 deletions

View File

@ -51,9 +51,9 @@ namespace osu.Game.Tests.Visual.Editing
[Test]
public void TestBindableBeatDivisor()
{
AddRepeatStep("move previous", () => bindableBeatDivisor.Previous(), 2);
AddRepeatStep("move previous", () => bindableBeatDivisor.SelectPrevious(), 2);
AddAssert("divisor is 4", () => bindableBeatDivisor.Value == 4);
AddRepeatStep("move next", () => bindableBeatDivisor.Next(), 1);
AddRepeatStep("move next", () => bindableBeatDivisor.SelectNext(), 1);
AddAssert("divisor is 12", () => bindableBeatDivisor.Value == 8);
}
@ -101,16 +101,22 @@ namespace osu.Game.Tests.Visual.Editing
public void TestBeatChevronNavigation()
{
switchBeatSnap(1);
assertBeatSnap(16);
switchBeatSnap(-4);
assertBeatSnap(1);
switchBeatSnap(3);
assertBeatSnap(8);
switchBeatSnap(-1);
switchBeatSnap(3);
assertBeatSnap(16);
switchBeatSnap(-2);
assertBeatSnap(4);
switchBeatSnap(-3);
assertBeatSnap(16);
assertBeatSnap(1);
}
[Test]
@ -207,7 +213,7 @@ namespace osu.Game.Tests.Visual.Editing
}, Math.Abs(direction));
private void assertBeatSnap(int expected) => AddAssert($"beat snap is {expected}",
() => bindableBeatDivisor.Value == expected);
() => bindableBeatDivisor.Value, () => Is.EqualTo(expected));
private void switchPresets(int direction) => AddRepeatStep($"move presets {(direction > 0 ? "forward" : "backward")}", () =>
{

View File

@ -101,6 +101,10 @@ namespace osu.Game.Input.Bindings
new KeyBinding(new[] { InputKey.Control, InputKey.J }, GlobalAction.EditorFlipVertically),
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.MouseWheelDown }, GlobalAction.EditorDecreaseDistanceSpacing),
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.MouseWheelUp }, GlobalAction.EditorIncreaseDistanceSpacing),
// Framework automatically converts wheel up/down to left/right when shift is held.
// See https://github.com/ppy/osu-framework/blob/master/osu.Framework/Input/StateChanges/MouseScrollRelativeInput.cs#L37-L38.
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.MouseWheelRight }, GlobalAction.EditorCyclePreviousBeatSnapDivisor),
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.MouseWheelLeft }, GlobalAction.EditorCycleNextBeatSnapDivisor),
};
public IEnumerable<KeyBinding> InGameKeyBindings => new[]
@ -355,6 +359,12 @@ namespace osu.Game.Input.Bindings
ToggleProfile,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCloneSelection))]
EditorCloneSelection
EditorCloneSelection,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCyclePreviousBeatSnapDivisor))]
EditorCyclePreviousBeatSnapDivisor,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCycleNextBeatSnapDivisor))]
EditorCycleNextBeatSnapDivisor,
}
}

View File

@ -279,6 +279,16 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString EditorDecreaseDistanceSpacing => new TranslatableString(getKey(@"editor_decrease_distance_spacing"), @"Decrease distance spacing");
/// <summary>
/// "Cycle previous beat snap divisor"
/// </summary>
public static LocalisableString EditorCyclePreviousBeatSnapDivisor => new TranslatableString(getKey(@"editor_cycle_previous_beat_snap_divisor"), @"Cycle previous beat snap divisor");
/// <summary>
/// "Cycle next beat snap divisor"
/// </summary>
public static LocalisableString EditorCycleNextBeatSnapDivisor => new TranslatableString(getKey(@"editor_cycle_next_snap_divisor"), @"Cycle next beat snap divisor");
/// <summary>
/// "Toggle skin editor"
/// </summary>

View File

@ -59,16 +59,18 @@ namespace osu.Game.Screens.Edit
Value = 1;
}
public void Next()
public void SelectNext()
{
var presets = ValidDivisors.Value.Presets;
Value = presets.Cast<int?>().SkipWhile(preset => preset != Value).ElementAtOrDefault(1) ?? presets[0];
if (presets.Cast<int?>().SkipWhile(preset => preset != Value).ElementAtOrDefault(1) is int newValue)
Value = newValue;
}
public void Previous()
public void SelectPrevious()
{
var presets = ValidDivisors.Value.Presets;
Value = presets.Cast<int?>().TakeWhile(preset => preset != Value).LastOrDefault() ?? presets[^1];
if (presets.Cast<int?>().TakeWhile(preset => preset != Value).LastOrDefault() is int newValue)
Value = newValue;
}
protected override int DefaultPrecision => 1;

View File

@ -16,12 +16,14 @@ using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
@ -29,7 +31,7 @@ using osuTK.Input;
namespace osu.Game.Screens.Edit.Compose.Components
{
public partial class BeatDivisorControl : CompositeDrawable
public partial class BeatDivisorControl : CompositeDrawable, IKeyBindingHandler<GlobalAction>
{
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
@ -101,13 +103,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
new ChevronButton
{
Icon = FontAwesome.Solid.ChevronLeft,
Action = beatDivisor.Previous
Action = beatDivisor.SelectPrevious
},
new DivisorDisplay { BeatDivisor = { BindTarget = beatDivisor } },
new ChevronButton
{
Icon = FontAwesome.Solid.ChevronRight,
Action = beatDivisor.Next
Action = beatDivisor.SelectNext
}
},
},
@ -220,6 +222,26 @@ namespace osu.Game.Screens.Edit.Compose.Components
return base.OnKeyDown(e);
}
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
switch (e.Action)
{
case GlobalAction.EditorCycleNextBeatSnapDivisor:
beatDivisor.SelectNext();
return true;
case GlobalAction.EditorCyclePreviousBeatSnapDivisor:
beatDivisor.SelectPrevious();
return true;
}
return false;
}
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
{
}
internal partial class DivisorDisplay : OsuAnimatedButton, IHasPopover
{
public BindableBeatDivisor BeatDivisor { get; } = new BindableBeatDivisor();
@ -442,12 +464,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
switch (e.Key)
{
case Key.Right:
beatDivisor.Next();
beatDivisor.SelectNext();
OnUserChange(Current.Value);
return true;
case Key.Left:
beatDivisor.Previous();
beatDivisor.SelectPrevious();
OnUserChange(Current.Value);
return true;