1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

Merge pull request #24683 from Wleter/skin-editor-selection-negative-scaling

Allow inverse scaling selection in skin editor
This commit is contained in:
Bartłomiej Dach 2023-09-01 22:06:21 +02:00 committed by GitHub
commit ac3d7327df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 8 deletions

View File

@ -47,10 +47,7 @@ namespace osu.Game.Overlays.SkinEditor
// copy to mutate, as we will need to compare to the original later on.
var adjustedRect = selectionRect;
// first, remove any scale axis we are not interested in.
if (anchor.HasFlagFast(Anchor.x1)) scale.X = 0;
if (anchor.HasFlagFast(Anchor.y1)) scale.Y = 0;
bool isRotated = false;
// for now aspect lock scale adjustments that occur at corners..
if (!anchor.HasFlagFast(Anchor.x1) && !anchor.HasFlagFast(Anchor.y1))
@ -61,8 +58,9 @@ namespace osu.Game.Overlays.SkinEditor
}
// ..or if any of the selection have been rotated.
// this is to avoid requiring skew logic (which would likely not be the user's expected transform anyway).
else if (SelectedBlueprints.Any(b => !Precision.AlmostEquals(((Drawable)b.Item).Rotation, 0)))
else if (SelectedBlueprints.Any(b => !Precision.AlmostEquals(((Drawable)b.Item).Rotation % 90, 0)))
{
isRotated = true;
if (anchor.HasFlagFast(Anchor.x1))
// if dragging from the horizontal centre, only a vertical component is available.
scale.X = scale.Y / selectionRect.Height * selectionRect.Width;
@ -74,13 +72,28 @@ namespace osu.Game.Overlays.SkinEditor
if (anchor.HasFlagFast(Anchor.x0)) adjustedRect.X -= scale.X;
if (anchor.HasFlagFast(Anchor.y0)) adjustedRect.Y -= scale.Y;
// Maintain the selection's centre position if dragging from the centre anchors and selection is rotated.
if (isRotated && anchor.HasFlagFast(Anchor.x1)) adjustedRect.X -= scale.X / 2;
if (isRotated && anchor.HasFlagFast(Anchor.y1)) adjustedRect.Y -= scale.Y / 2;
adjustedRect.Width += scale.X;
adjustedRect.Height += scale.Y;
if (adjustedRect.Width <= 0 || adjustedRect.Height <= 0)
{
Axes toFlip = Axes.None;
if (adjustedRect.Width <= 0) toFlip |= Axes.X;
if (adjustedRect.Height <= 0) toFlip |= Axes.Y;
SelectionBox.PerformFlipFromScaleHandles(toFlip);
return true;
}
// scale adjust applied to each individual item should match that of the quad itself.
var scaledDelta = new Vector2(
MathF.Max(adjustedRect.Width / selectionRect.Width, 0),
MathF.Max(adjustedRect.Height / selectionRect.Height, 0)
adjustedRect.Width / selectionRect.Width,
adjustedRect.Height / selectionRect.Height
);
foreach (var b in SelectedBlueprints)
@ -102,7 +115,12 @@ namespace osu.Game.Overlays.SkinEditor
);
updateDrawablePosition(drawableItem, newPositionInAdjusted);
drawableItem.Scale *= scaledDelta;
var currentScaledDelta = scaledDelta;
if (Precision.AlmostEquals(MathF.Abs(drawableItem.Rotation) % 180, 90))
currentScaledDelta = new Vector2(scaledDelta.Y, scaledDelta.X);
drawableItem.Scale *= currentScaledDelta;
}
return true;

View File

@ -4,6 +4,7 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -307,6 +308,25 @@ namespace osu.Game.Screens.Edit.Compose.Components
return button;
}
/// <remarks>
/// This method should be called when a selection needs to be flipped
/// because of an ongoing scale handle drag that would otherwise cause width or height to go negative.
/// </remarks>
public void PerformFlipFromScaleHandles(Axes axes)
{
if (axes.HasFlagFast(Axes.X))
{
dragHandles.FlipScaleHandles(Direction.Horizontal);
OnFlip?.Invoke(Direction.Horizontal, false);
}
if (axes.HasFlagFast(Axes.Y))
{
dragHandles.FlipScaleHandles(Direction.Vertical);
OnFlip?.Invoke(Direction.Vertical, false);
}
}
private void addScaleHandle(Anchor anchor)
{
var handle = new SelectionBoxScaleHandle

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -69,6 +70,17 @@ namespace osu.Game.Screens.Edit.Compose.Components
allDragHandles.Add(handle);
}
public void FlipScaleHandles(Direction direction)
{
foreach (var handle in scaleHandles)
{
if (direction == Direction.Horizontal && !handle.Anchor.HasFlagFast(Anchor.x1))
handle.Anchor ^= Anchor.x0 | Anchor.x2;
if (direction == Direction.Vertical && !handle.Anchor.HasFlagFast(Anchor.y1))
handle.Anchor ^= Anchor.y0 | Anchor.y2;
}
}
private SelectionBoxRotationHandle displayedRotationHandle;
private SelectionBoxDragHandle activeHandle;