1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-13 16:13:34 +08:00

Merge pull request #24059 from peppy/add-editor-rotate-hotkeys

Add support for `Ctrl` + `<` / `>` to rotate selection in editor
This commit is contained in:
Dean Herbert 2023-06-28 12:03:34 +09:00 committed by GitHub
commit 076f41be12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 35 deletions

View File

@ -101,6 +101,38 @@ namespace osu.Game.Tests.Visual.Editing
AddAssert("objects reverted to original position", () => addedObjects[0].StartTime == 100);
}
[Test]
public void TestRotateHotkeys()
{
HitCircle[] addedObjects = null;
AddStep("add hitobjects", () => EditorBeatmap.AddRange(addedObjects = new[]
{
new HitCircle { StartTime = 100 },
new HitCircle { StartTime = 200, Position = new Vector2(100) },
new HitCircle { StartTime = 300, Position = new Vector2(200) },
new HitCircle { StartTime = 400, Position = new Vector2(300) },
}));
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.AddRange(addedObjects));
AddStep("rotate clockwise", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Key(Key.Period);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddAssert("objects rotated clockwise", () => addedObjects[0].Position == new Vector2(300, 0));
AddStep("rotate counterclockwise", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Key(Key.Comma);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddAssert("objects reverted to original position", () => addedObjects[0].Position == new Vector2(0));
}
[Test]
public void TestBasicSelect()
{

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -24,13 +22,17 @@ namespace osu.Game.Screens.Edit.Compose.Components
private const float button_padding = 5;
public Func<float, bool> OnRotation;
public Func<Vector2, Anchor, bool> OnScale;
public Func<Direction, bool, bool> OnFlip;
public Func<bool> OnReverse;
public Func<float, bool>? OnRotation;
public Func<Vector2, Anchor, bool>? OnScale;
public Func<Direction, bool, bool>? OnFlip;
public Func<bool>? OnReverse;
public Action OperationStarted;
public Action OperationEnded;
public Action? OperationStarted;
public Action? OperationEnded;
private SelectionBoxButton? reverseButton;
private SelectionBoxButton? rotateClockwiseButton;
private SelectionBoxButton? rotateCounterClockwiseButton;
private bool canReverse;
@ -134,7 +136,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
}
}
private string text;
private string text = string.Empty;
public string Text
{
@ -150,13 +152,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
}
}
private SelectionBoxDragHandleContainer dragHandles;
private FillFlowContainer buttons;
private SelectionBoxDragHandleContainer dragHandles = null!;
private FillFlowContainer buttons = null!;
private OsuSpriteText selectionDetailsText;
private OsuSpriteText? selectionDetailsText;
[Resolved]
private OsuColour colours { get; set; }
private OsuColour colours { get; set; } = null!;
[BackgroundDependencyLoader]
private void load() => recreate();
@ -166,19 +168,16 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (e.Repeat || !e.ControlPressed)
return false;
bool runOperationFromHotkey(Func<bool> operation)
{
operationStarted();
bool result = operation?.Invoke() ?? false;
operationEnded();
return result;
}
switch (e.Key)
{
case Key.G:
return CanReverse && runOperationFromHotkey(OnReverse);
return CanReverse && reverseButton?.TriggerClick() == true;
case Key.Comma:
return CanRotate && rotateCounterClockwiseButton?.TriggerClick() == true;
case Key.Period:
return CanRotate && rotateClockwiseButton?.TriggerClick() == true;
}
return base.OnKeyDown(e);
@ -256,13 +255,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (CanFlipX) addXFlipComponents();
if (CanFlipY) addYFlipComponents();
if (CanRotate) addRotationComponents();
if (CanReverse) addButton(FontAwesome.Solid.Backward, "Reverse pattern (Ctrl-G)", () => OnReverse?.Invoke());
if (CanReverse) reverseButton = addButton(FontAwesome.Solid.Backward, "Reverse pattern (Ctrl-G)", () => OnReverse?.Invoke());
}
private void addRotationComponents()
{
addButton(FontAwesome.Solid.Undo, "Rotate 90 degrees counter-clockwise", () => OnRotation?.Invoke(-90));
addButton(FontAwesome.Solid.Redo, "Rotate 90 degrees clockwise", () => OnRotation?.Invoke(90));
rotateCounterClockwiseButton = addButton(FontAwesome.Solid.Undo, "Rotate 90 degrees counter-clockwise (Ctrl-<)", () => OnRotation?.Invoke(-90));
rotateClockwiseButton = addButton(FontAwesome.Solid.Redo, "Rotate 90 degrees clockwise (Ctrl->)", () => OnRotation?.Invoke(90));
addRotateHandle(Anchor.TopLeft);
addRotateHandle(Anchor.TopRight);
@ -300,7 +299,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
addButton(FontAwesome.Solid.ArrowsAltV, "Flip vertically", () => OnFlip?.Invoke(Direction.Vertical, false));
}
private void addButton(IconUsage icon, string tooltip, Action action)
private SelectionBoxButton addButton(IconUsage icon, string tooltip, Action action)
{
var button = new SelectionBoxButton(icon, tooltip)
{
@ -310,6 +309,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
button.OperationStarted += operationStarted;
button.OperationEnded += operationEnded;
buttons.Add(button);
return button;
}
private void addScaleHandle(Anchor anchor)

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -17,11 +15,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
public sealed partial class SelectionBoxButton : SelectionBoxControl, IHasTooltip
{
private SpriteIcon icon;
private SpriteIcon icon = null!;
private readonly IconUsage iconUsage;
public Action Action;
public Action? Action;
public SelectionBoxButton(IconUsage iconUsage, string tooltip)
{
@ -49,6 +47,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected override bool OnClick(ClickEvent e)
{
Circle.FlashColour(Colours.GrayF, 300);
TriggerOperationStarted();
Action?.Invoke();
TriggerOperationEnded();

View File

@ -24,7 +24,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
public event Action OperationStarted;
public event Action OperationEnded;
private Circle circle;
protected Circle Circle { get; private set; }
/// <summary>
/// Whether the user is currently holding the control with mouse.
@ -41,7 +41,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
InternalChildren = new Drawable[]
{
circle = new Circle
Circle = new Circle
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
@ -85,9 +85,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected virtual void UpdateHoverState()
{
if (IsHeld)
circle.FadeColour(Colours.GrayF, TRANSFORM_DURATION, Easing.OutQuint);
Circle.FadeColour(Colours.GrayF, TRANSFORM_DURATION, Easing.OutQuint);
else
circle.FadeColour(IsHovered ? Colours.Red : Colours.YellowDark, TRANSFORM_DURATION, Easing.OutQuint);
Circle.FadeColour(IsHovered ? Colours.Red : Colours.YellowDark, TRANSFORM_DURATION, Easing.OutQuint);
this.ScaleTo(IsHeld || IsHovered ? 1.5f : 1, TRANSFORM_DURATION, Easing.OutQuint);
}