Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support scaling around center when scaling with select box #29949

Merged
merged 5 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
{
}

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);
Expand Down
2 changes: 2 additions & 0 deletions osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ private void handleToggleViaKey(KeyboardEvent key)
gridSnapMomentary = shiftPressed;
rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False;
}

DistanceSnapProvider.HandleToggleViaKey(key);
}

private DistanceSnapGrid createDistanceSnapGrid(IEnumerable<HitObject> selectedHitObjects)
Expand Down
136 changes: 136 additions & 0 deletions osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -36,6 +37,9 @@ private ComposeBlueprintContainer blueprintContainer
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", () =>
Expand Down Expand Up @@ -519,5 +523,137 @@ public void TestQuickDeleteRemovesSliderControlPoint()

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));
}
}
}
17 changes: 1 addition & 16 deletions osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,7 @@ public IEnumerable<TernaryButton> CreateTernaryButtons() => new[]
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)
bdach marked this conversation as resolved.
Show resolved Hide resolved
{
bool altPressed = key.AltPressed;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ protected override void OnDrag(DragEvent e)

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;
}

Expand All @@ -69,7 +69,7 @@ protected override void OnKeyUp(KeyUpEvent e)
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)
Expand Down Expand Up @@ -100,13 +100,13 @@ private void adjustScaleFromAnchor(ref Vector2 scale)
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());
}

Expand Down
Loading