1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 16:25:32 +08:00

Merge pull request #29949 from minetoblend/feature/scale-around-center

Support scaling around center when scaling with select box
This commit is contained in:
Dean Herbert 2024-09-28 21:37:39 +09:00 committed by GitHub
commit c46d787f1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 164 additions and 21 deletions

View File

@ -114,6 +114,26 @@ namespace osu.Game.Rulesets.Catch.Edit
{
}
protected override bool OnKeyDown(KeyDownEvent e)
{
if (e.Repeat)
return false;
handleToggleViaKey(e);
return base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyUpEvent e)
{
handleToggleViaKey(e);
base.OnKeyUp(e);
}
private void handleToggleViaKey(KeyboardEvent key)
{
DistanceSnapProvider.HandleToggleViaKey(key);
}
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
var result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType);

View File

@ -369,6 +369,8 @@ namespace osu.Game.Rulesets.Osu.Edit
gridSnapMomentary = shiftPressed;
rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False;
}
DistanceSnapProvider.HandleToggleViaKey(key);
}
private DistanceSnapGrid createDistanceSnapGrid(IEnumerable<HitObject> selectedHitObjects)

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
@ -36,6 +37,9 @@ namespace osu.Game.Tests.Visual.Editing
private ContextMenuContainer contextMenuContainer
=> Editor.ChildrenOfType<ContextMenuContainer>().First();
private SelectionBoxScaleHandle getScaleHandle(Anchor anchor)
=> Editor.ChildrenOfType<SelectionBoxScaleHandle>().First(it => it.Anchor == anchor);
private void moveMouseToObject(Func<HitObject> targetFunc)
{
AddStep("move mouse to object", () =>
@ -519,5 +523,137 @@ namespace osu.Game.Tests.Visual.Editing
AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft));
}
[Test]
public void TestShiftModifierMaintainsAspectRatio()
{
HitCircle[] addedObjects = null!;
float aspectRatioBeforeDrag = 0;
float getAspectRatio() => (addedObjects[1].X - addedObjects[0].X) / (addedObjects[1].Y - addedObjects[0].Y);
AddStep("add hitobjects", () =>
{
EditorBeatmap.AddRange(addedObjects = new[]
{
new HitCircle { StartTime = 100, Position = new Vector2(150, 150) },
new HitCircle { StartTime = 200, Position = new Vector2(250, 200) },
});
aspectRatioBeforeDrag = getAspectRatio();
});
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.AddRange(addedObjects));
AddStep("move mouse to handle", () => InputManager.MoveMouseTo(getScaleHandle(Anchor.BottomRight).ScreenSpaceDrawQuad.Centre));
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0)));
AddStep("aspect ratio does not equal", () => Assert.AreNotEqual(aspectRatioBeforeDrag, getAspectRatio()));
AddStep("press shift", () => InputManager.PressKey(Key.ShiftLeft));
AddStep("aspect ratio does equal", () => Assert.AreEqual(aspectRatioBeforeDrag, getAspectRatio()));
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft));
}
[Test]
public void TestAltModifierScalesAroundCenter()
{
HitCircle[] addedObjects = null!;
Vector2 centerBeforeDrag = Vector2.Zero;
Vector2 getCenter() => (addedObjects[0].Position + addedObjects[1].Position) / 2;
AddStep("add hitobjects", () =>
{
EditorBeatmap.AddRange(addedObjects = new[]
{
new HitCircle { StartTime = 100, Position = new Vector2(150, 150) },
new HitCircle { StartTime = 200, Position = new Vector2(250, 200) },
});
centerBeforeDrag = getCenter();
});
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.AddRange(addedObjects));
AddStep("move mouse to handle", () => InputManager.MoveMouseTo(getScaleHandle(Anchor.BottomRight).ScreenSpaceDrawQuad.Centre));
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0)));
AddStep("center does not equal", () => Assert.AreNotEqual(centerBeforeDrag, getCenter()));
AddStep("press alt", () => InputManager.PressKey(Key.AltLeft));
AddStep("center does equal", () => Assert.AreEqual(centerBeforeDrag, getCenter()));
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("release alt", () => InputManager.ReleaseKey(Key.AltLeft));
}
[Test]
public void TestShiftAndAltModifierKeys()
{
HitCircle[] addedObjects = null!;
float aspectRatioBeforeDrag = 0;
Vector2 centerBeforeDrag = Vector2.Zero;
float getAspectRatio() => (addedObjects[1].X - addedObjects[0].X) / (addedObjects[1].Y - addedObjects[0].Y);
Vector2 getCenter() => (addedObjects[0].Position + addedObjects[1].Position) / 2;
AddStep("add hitobjects", () =>
{
EditorBeatmap.AddRange(addedObjects = new[]
{
new HitCircle { StartTime = 100, Position = new Vector2(150, 150) },
new HitCircle { StartTime = 200, Position = new Vector2(250, 200) },
});
aspectRatioBeforeDrag = getAspectRatio();
centerBeforeDrag = getCenter();
});
AddStep("select objects", () => EditorBeatmap.SelectedHitObjects.AddRange(addedObjects));
AddStep("move mouse to handle", () => InputManager.MoveMouseTo(getScaleHandle(Anchor.BottomRight).ScreenSpaceDrawQuad.Centre));
AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left));
AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0)));
AddStep("aspect ratio does not equal", () => Assert.AreNotEqual(aspectRatioBeforeDrag, getAspectRatio()));
AddStep("center does not equal", () => Assert.AreNotEqual(centerBeforeDrag, getCenter()));
AddStep("press shift", () => InputManager.PressKey(Key.ShiftLeft));
AddStep("aspect ratio does equal", () => Assert.AreEqual(aspectRatioBeforeDrag, getAspectRatio()));
AddStep("center does not equal", () => Assert.AreNotEqual(centerBeforeDrag, getCenter()));
AddStep("press alt", () => InputManager.PressKey(Key.AltLeft));
AddStep("center does equal", () => Assert.AreEqual(centerBeforeDrag, getCenter()));
AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft));
AddStep("release alt", () => InputManager.ReleaseKey(Key.AltLeft));
}
}
}

View File

@ -195,22 +195,7 @@ namespace osu.Game.Rulesets.Edit
new TernaryButton(DistanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = OsuIcon.EditorDistanceSnap })
};
protected override bool OnKeyDown(KeyDownEvent e)
{
if (e.Repeat)
return false;
handleToggleViaKey(e);
return base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyUpEvent e)
{
handleToggleViaKey(e);
base.OnKeyUp(e);
}
private void handleToggleViaKey(KeyboardEvent key)
public void HandleToggleViaKey(KeyboardEvent key)
{
bool altPressed = key.AltPressed;

View File

@ -50,14 +50,14 @@ namespace osu.Game.Screens.Edit.Compose.Components
rawScale = convertDragEventToScaleMultiplier(e);
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed);
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, useDefaultOrigin: e.AltPressed);
}
protected override bool OnKeyDown(KeyDownEvent e)
{
if (IsDragged)
{
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed);
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, useDefaultOrigin: e.AltPressed);
return true;
}
@ -69,7 +69,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
base.OnKeyUp(e);
if (IsDragged)
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed);
applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, useDefaultOrigin: e.AltPressed);
}
protected override void OnDragEnd(DragEndEvent e)
@ -100,13 +100,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
if ((originalAnchor & Anchor.y0) > 0) scale.Y = -scale.Y;
}
private void applyScale(bool shouldLockAspectRatio)
private void applyScale(bool shouldLockAspectRatio, bool useDefaultOrigin = false)
{
var newScale = shouldLockAspectRatio
? new Vector2((rawScale.X + rawScale.Y) * 0.5f)
: rawScale;
var scaleOrigin = originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value);
Vector2? scaleOrigin = useDefaultOrigin ? null : originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value);
scaleHandler!.Update(newScale, scaleOrigin, getAdjustAxis());
}