1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

Add simple key based time nudging support to editor

This commit is contained in:
Dean Herbert 2021-04-22 18:47:04 +09:00
parent 1884c18a2c
commit a5364b224f
3 changed files with 71 additions and 1 deletions

View File

@ -41,6 +41,28 @@ namespace osu.Game.Tests.Visual.Editing
});
}
[Test]
public void TestNudgeSelection()
{
HitCircle[] addedObjects = null;
AddStep("add hitobjects", () => EditorBeatmap.AddRange(addedObjects = new[]
{
new HitCircle { StartTime = 100 },
new HitCircle { StartTime = 200, Position = new Vector2(50) },
new HitCircle { StartTime = 300, Position = new Vector2(100) },
new HitCircle { StartTime = 400, Position = new Vector2(150) },
}));
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.AddRange(addedObjects));
AddStep("nudge forwards", () => InputManager.Key(Key.K));
AddAssert("objects moved forwards in time", () => addedObjects[0].StartTime > 100);
AddStep("nudge backwards", () => InputManager.Key(Key.J));
AddAssert("objects reverted to original position", () => addedObjects[0].StartTime == 100);
}
[Test]
public void TestBasicSelect()
{

View File

@ -71,6 +71,8 @@ namespace osu.Game.Input.Bindings
new KeyBinding(new[] { InputKey.F3 }, GlobalAction.EditorTimingMode),
new KeyBinding(new[] { InputKey.F4 }, GlobalAction.EditorSetupMode),
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.A }, GlobalAction.EditorVerifyMode),
new KeyBinding(new[] { InputKey.J }, GlobalAction.EditorNudgeLeft),
new KeyBinding(new[] { InputKey.K }, GlobalAction.EditorNudgeRight),
};
public IEnumerable<KeyBinding> InGameKeyBindings => new[]
@ -251,5 +253,11 @@ namespace osu.Game.Input.Bindings
[Description("Verify mode")]
EditorVerifyMode,
[Description("Nudge selection left")]
EditorNudgeLeft,
[Description("Nudge selection right")]
EditorNudgeRight
}
}

View File

@ -12,9 +12,11 @@ using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
@ -237,10 +239,48 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
}
internal class TimelineSelectionHandler : SelectionHandler
internal class TimelineSelectionHandler : SelectionHandler, IKeyBindingHandler<GlobalAction>
{
// for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation
public override bool HandleMovement(MoveSelectionEvent moveEvent) => true;
public bool OnPressed(GlobalAction action)
{
switch (action)
{
case GlobalAction.EditorNudgeLeft:
nudgeSelection(-1);
return true;
case GlobalAction.EditorNudgeRight:
nudgeSelection(1);
return true;
}
return false;
}
public void OnReleased(GlobalAction action)
{
}
/// <summary>
/// Nudge the current selection by the specified multiple of beat divisor lengths,
/// based on the timing at the first object in the selection.
/// </summary>
/// <param name="amount">The direction and count of beat divisor lengths to adjust.</param>
private void nudgeSelection(int amount)
{
var selected = EditorBeatmap.SelectedHitObjects;
if (selected.Count == 0)
return;
var timingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(selected.First().StartTime);
double adjustment = timingPoint.BeatLength / EditorBeatmap.BeatDivisor * amount;
EditorBeatmap.PerformOnSelection(h => h.StartTime += adjustment);
}
}
private class TimelineDragBox : DragBox