From 2dbbbe270daf475afeec30539af438d08de1956e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Sat, 21 Sep 2024 13:37:41 +0200 Subject: [PATCH 1/5] Scale around center when pressing alt while dragging selection box scale handle --- .../Edit/Compose/Components/SelectionBoxScaleHandle.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs index 7b0943c1d0..42e7b8c219 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs @@ -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, ignoreAnchor: e.AltPressed); } protected override bool OnKeyDown(KeyDownEvent e) { if (IsDragged) { - applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed); + applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, ignoreAnchor: 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, ignoreAnchor: 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 ignoreAnchor = false) { var newScale = shouldLockAspectRatio ? new Vector2((rawScale.X + rawScale.Y) * 0.5f) : rawScale; - var scaleOrigin = originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value); + Vector2? scaleOrigin = ignoreAnchor ? null : originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value); scaleHandler!.Update(newScale, scaleOrigin, getAdjustAxis()); } From 3180468db1001294266b2f59f1451802c6e2b1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Sat, 21 Sep 2024 14:22:17 +0200 Subject: [PATCH 2/5] Prevent the distance snap grid from being activated by alt key while dragging select box handle --- .../Edit/CatchHitObjectComposer.cs | 20 +++++++++++++++++++ .../Edit/OsuHitObjectComposer.cs | 2 ++ .../Edit/ComposerDistanceSnapProvider.cs | 17 +--------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 83f48816f9..978aeba4ce 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -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); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 8fc2a9b7d3..c94dba6b23 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -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 selectedHitObjects) diff --git a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs index b9850a94a3..979492fd8b 100644 --- a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs @@ -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; From b54b4063bece8eac19e4364773c2ab842fafc636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Tue, 24 Sep 2024 12:40:28 +0200 Subject: [PATCH 3/5] Rename parameter --- .../Edit/Compose/Components/SelectionBoxScaleHandle.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs index 42e7b8c219..3b7e29cf3d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs @@ -50,14 +50,14 @@ namespace osu.Game.Screens.Edit.Compose.Components rawScale = convertDragEventToScaleMultiplier(e); - applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, ignoreAnchor: e.AltPressed); + applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, useDefaultOrigin: e.AltPressed); } protected override bool OnKeyDown(KeyDownEvent e) { if (IsDragged) { - applyScale(shouldLockAspectRatio: isCornerAnchor(originalAnchor) && e.ShiftPressed, ignoreAnchor: e.AltPressed); + 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, ignoreAnchor: e.AltPressed); + 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, bool ignoreAnchor = false) + private void applyScale(bool shouldLockAspectRatio, bool useDefaultOrigin = false) { var newScale = shouldLockAspectRatio ? new Vector2((rawScale.X + rawScale.Y) * 0.5f) : rawScale; - Vector2? scaleOrigin = ignoreAnchor ? null : originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value); + Vector2? scaleOrigin = useDefaultOrigin ? null : originalAnchor.Opposite().PositionOnQuad(scaleHandler!.OriginalSurroundingQuad!.Value); scaleHandler!.Update(newScale, scaleOrigin, getAdjustAxis()); } From 3ad734296473eae7fcfd91b3ed11b43fcc0d4774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Tue, 24 Sep 2024 13:35:56 +0200 Subject: [PATCH 4/5] Add tests for shift and alt modifiers in select box --- .../Editing/TestSceneComposerSelection.cs | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs index 3884a3108f..3d7aef5a65 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs @@ -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().First(); + private SelectionBoxScaleHandle getScaleHandle(Anchor anchor) + => Editor.ChildrenOfType().First(it => it.Anchor == anchor); + private void moveMouseToObject(Func 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))); + + 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))); + + 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))); + + 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)); + } } } From 15c4b1dc8f81dd4db100854cde33f928db6307ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Tue, 24 Sep 2024 13:45:03 +0200 Subject: [PATCH 5/5] Move mouse horizontally in test to make sure it doesn't accidentally maintain aspect ratio --- osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs index 3d7aef5a65..cbc9088d04 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs @@ -550,7 +550,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left)); - AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50))); + AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0))); AddStep("aspect ratio does not equal", () => Assert.AreNotEqual(aspectRatioBeforeDrag, getAspectRatio())); @@ -589,7 +589,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left)); - AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50))); + AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0))); AddStep("center does not equal", () => Assert.AreNotEqual(centerBeforeDrag, getCenter())); @@ -633,7 +633,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left)); - AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50))); + AddStep("move mouse", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(50, 0))); AddStep("aspect ratio does not equal", () => Assert.AreNotEqual(aspectRatioBeforeDrag, getAspectRatio()));