diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 706c41c2e3..1f250f078d 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -41,37 +41,16 @@ namespace osu.Game.Rulesets.Osu.Edit /// private Vector2? referenceOrigin; - public override bool HandleScaleY(in float scale, Anchor reference) => - scaleSelection(new Vector2(0, ((reference & Anchor.y0) > 0 ? -1 : 1) * scale), reference); - - public override bool HandleScaleX(in float scale, Anchor reference) => - scaleSelection(new Vector2(((reference & Anchor.x0) > 0 ? -1 : 1) * scale, 0), reference); - - public override bool HandleRotation(float delta) + public override bool HandleScale(Vector2 scale, Anchor reference) { - var hitObjects = selectedMovableObjects; + // cancel out scale in axes we don't care about (based on which drag handle was used). + if ((reference & Anchor.x1) > 0) scale.X = 0; + if ((reference & Anchor.y1) > 0) scale.Y = 0; - Quad quad = getSurroundingQuad(hitObjects); + // reverse the scale direction if dragging from top or left. + if ((reference & Anchor.x0) > 0) scale.X = -scale.X; + if ((reference & Anchor.y0) > 0) scale.Y = -scale.Y; - referenceOrigin ??= quad.Centre; - - foreach (var h in hitObjects) - { - h.Position = rotatePointAroundOrigin(h.Position, referenceOrigin.Value, delta); - - if (h is IHasPath path) - { - foreach (var point in path.Path.ControlPoints) - point.Position.Value = rotatePointAroundOrigin(point.Position.Value, Vector2.Zero, delta); - } - } - - // this isn't always the case but let's be lenient for now. - return true; - } - - private bool scaleSelection(Vector2 scale, Anchor reference) - { var hitObjects = selectedMovableObjects; // for the time being, allow resizing of slider paths only if the slider is @@ -110,6 +89,29 @@ namespace osu.Game.Rulesets.Osu.Edit return true; } + public override bool HandleRotation(float delta) + { + var hitObjects = selectedMovableObjects; + + Quad quad = getSurroundingQuad(hitObjects); + + referenceOrigin ??= quad.Centre; + + foreach (var h in hitObjects) + { + h.Position = rotatePointAroundOrigin(h.Position, referenceOrigin.Value, delta); + + if (h is IHasPath path) + { + foreach (var point in path.Path.ControlPoints) + point.Position.Value = rotatePointAroundOrigin(point.Position.Value, Vector2.Zero, delta); + } + } + + // this isn't always the case but let's be lenient for now. + return true; + } + private bool moveSelection(Vector2 delta) { var hitObjects = selectedMovableObjects; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs index 4b12000fc3..a1fb91024b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs @@ -32,8 +32,7 @@ namespace osu.Game.Tests.Visual.Editing CanScaleY = true, OnRotation = handleRotation, - OnScaleX = handleScaleX, - OnScaleY = handleScaleY, + OnScale = handleScale } } }); @@ -43,24 +42,28 @@ namespace osu.Game.Tests.Visual.Editing AddToggleStep("toggle y", state => selectionBox.CanScaleY = state); } - private void handleScaleY(DragEvent e, Anchor reference) + private void handleScale(DragEvent e, Anchor reference) { - int direction = (reference & Anchor.y0) > 0 ? -1 : 1; - if (direction < 0) - selectionArea.Y += e.Delta.Y; - selectionArea.Height += direction * e.Delta.Y; - } + if ((reference & Anchor.y1) == 0) + { + int directionY = (reference & Anchor.y0) > 0 ? -1 : 1; + if (directionY < 0) + selectionArea.Y += e.Delta.Y; + selectionArea.Height += directionY * e.Delta.Y; + } - private void handleScaleX(DragEvent e, Anchor reference) - { - int direction = (reference & Anchor.x0) > 0 ? -1 : 1; - if (direction < 0) - selectionArea.X += e.Delta.X; - selectionArea.Width += direction * e.Delta.X; + if ((reference & Anchor.x1) == 0) + { + int directionX = (reference & Anchor.x0) > 0 ? -1 : 1; + if (directionX < 0) + selectionArea.X += e.Delta.X; + selectionArea.Width += directionX * e.Delta.X; + } } private void handleRotation(DragEvent e) { + // kinda silly and wrong, but just showing that the drag handles work. selectionArea.Rotation += e.Delta.X; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeSelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeSelectionBox.cs index dba1965569..424705c755 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeSelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeSelectionBox.cs @@ -17,8 +17,7 @@ namespace osu.Game.Screens.Edit.Compose.Components public class ComposeSelectionBox : CompositeDrawable { public Action OnRotation; - public Action OnScaleX; - public Action OnScaleY; + public Action OnScale; public Action OperationStarted; public Action OperationEnded; @@ -128,20 +127,8 @@ namespace osu.Game.Screens.Edit.Compose.Components { AddRangeInternal(new[] { - new DragHandle - { - Anchor = Anchor.TopCentre, - HandleDrag = e => OnScaleY?.Invoke(e, Anchor.TopCentre), - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, - new DragHandle - { - Anchor = Anchor.BottomCentre, - HandleDrag = e => OnScaleY?.Invoke(e, Anchor.BottomCentre), - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, + createDragHandle(Anchor.TopCentre), + createDragHandle(Anchor.BottomCentre), }); } @@ -149,20 +136,8 @@ namespace osu.Game.Screens.Edit.Compose.Components { AddRangeInternal(new[] { - new DragHandle - { - Anchor = Anchor.CentreLeft, - HandleDrag = e => OnScaleX?.Invoke(e, Anchor.CentreLeft), - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, - new DragHandle - { - Anchor = Anchor.CentreRight, - HandleDrag = e => OnScaleX?.Invoke(e, Anchor.CentreRight), - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, + createDragHandle(Anchor.CentreLeft), + createDragHandle(Anchor.CentreRight), }); } @@ -170,52 +145,20 @@ namespace osu.Game.Screens.Edit.Compose.Components { AddRangeInternal(new[] { - new DragHandle - { - Anchor = Anchor.TopLeft, - HandleDrag = e => - { - OnScaleX?.Invoke(e, Anchor.TopLeft); - OnScaleY?.Invoke(e, Anchor.TopLeft); - }, - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, - new DragHandle - { - Anchor = Anchor.TopRight, - HandleDrag = e => - { - OnScaleX?.Invoke(e, Anchor.TopRight); - OnScaleY?.Invoke(e, Anchor.TopRight); - }, - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, - new DragHandle - { - Anchor = Anchor.BottomLeft, - HandleDrag = e => - { - OnScaleX?.Invoke(e, Anchor.BottomLeft); - OnScaleY?.Invoke(e, Anchor.BottomLeft); - }, - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, - new DragHandle - { - Anchor = Anchor.BottomRight, - HandleDrag = e => - { - OnScaleX?.Invoke(e, Anchor.BottomRight); - OnScaleY?.Invoke(e, Anchor.BottomRight); - }, - OperationStarted = operationStarted, - OperationEnded = operationEnded - }, + createDragHandle(Anchor.TopLeft), + createDragHandle(Anchor.TopRight), + createDragHandle(Anchor.BottomLeft), + createDragHandle(Anchor.BottomRight), }); } + + ScaleDragHandle createDragHandle(Anchor anchor) => + new ScaleDragHandle(anchor) + { + HandleDrag = e => OnScale?.Invoke(e, anchor), + OperationStarted = operationStarted, + OperationEnded = operationEnded + }; } private int activeOperations; @@ -232,6 +175,14 @@ namespace osu.Game.Screens.Edit.Compose.Components OperationStarted?.Invoke(); } + private class ScaleDragHandle : DragHandle + { + public ScaleDragHandle(Anchor anchor) + { + Anchor = anchor; + } + } + private class RotationDragHandle : DragHandle { private SpriteIcon icon; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 6cd503b580..5ed9bb65a8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// copyright (c) ppy pty ltd . licensed under the mit licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -101,8 +101,7 @@ namespace osu.Game.Screens.Edit.Compose.Components OperationEnded = OnDragOperationEnded, OnRotation = e => HandleRotation(e.Delta.X), - OnScaleX = (e, anchor) => HandleScaleX(e.Delta.X, anchor), - OnScaleY = (e, anchor) => HandleScaleY(e.Delta.Y, anchor), + OnScale = (e, anchor) => HandleScale(e.Delta, anchor), }; /// @@ -145,20 +144,12 @@ namespace osu.Game.Screens.Edit.Compose.Components public virtual bool HandleRotation(float angle) => false; /// - /// Handles the selected s being scaled in a vertical direction. + /// Handles the selected s being scaled. /// - /// The delta scale to apply. + /// The delta scale to apply, in playfield local coordinates. /// The point of reference where the scale is originating from. /// Whether any s could be moved. - public virtual bool HandleScaleY(in float scale, Anchor anchor) => false; - - /// - /// Handles the selected s being scaled in a horizontal direction. - /// - /// The delta scale to apply. - /// The point of reference where the scale is originating from. - /// Whether any s could be moved. - public virtual bool HandleScaleX(in float scale, Anchor anchor) => false; + public virtual bool HandleScale(Vector2 scale, Anchor anchor) => false; public bool OnPressed(PlatformAction action) {