2021-04-24 12:44:33 +08:00
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
|
|
|
|
using osu.Framework.Allocation;
|
2022-01-09 00:19:52 +08:00
|
|
|
using osu.Framework.Graphics;
|
|
|
|
using osu.Framework.Input.Events;
|
2024-01-20 23:49:10 +08:00
|
|
|
using osu.Framework.Utils;
|
2021-04-24 12:44:33 +08:00
|
|
|
using osuTK;
|
2024-01-20 07:22:53 +08:00
|
|
|
using osuTK.Input;
|
2021-04-24 12:44:33 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Screens.Edit.Compose.Components
|
|
|
|
{
|
2022-11-24 13:32:20 +08:00
|
|
|
public partial class SelectionBoxScaleHandle : SelectionBoxDragHandle
|
2021-04-24 12:44:33 +08:00
|
|
|
{
|
2024-01-20 07:22:53 +08:00
|
|
|
[Resolved]
|
|
|
|
private SelectionScaleHandler? scaleHandler { get; set; }
|
2022-01-09 00:19:52 +08:00
|
|
|
|
2021-04-24 12:44:33 +08:00
|
|
|
[BackgroundDependencyLoader]
|
|
|
|
private void load()
|
|
|
|
{
|
|
|
|
Size = new Vector2(10);
|
|
|
|
}
|
2022-01-09 00:19:52 +08:00
|
|
|
|
2024-01-20 20:04:05 +08:00
|
|
|
private Anchor originalAnchor;
|
|
|
|
|
2024-01-20 07:22:53 +08:00
|
|
|
protected override bool OnDragStart(DragStartEvent e)
|
|
|
|
{
|
|
|
|
if (e.Button != MouseButton.Left)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (scaleHandler == null) return false;
|
|
|
|
|
2024-01-20 20:04:05 +08:00
|
|
|
originalAnchor = Anchor;
|
|
|
|
|
2024-01-20 07:22:53 +08:00
|
|
|
scaleHandler.Begin();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Vector2 rawScale;
|
|
|
|
|
2022-01-09 00:19:52 +08:00
|
|
|
protected override void OnDrag(DragEvent e)
|
|
|
|
{
|
|
|
|
base.OnDrag(e);
|
2024-01-20 07:22:53 +08:00
|
|
|
|
|
|
|
if (scaleHandler == null) return;
|
|
|
|
|
|
|
|
rawScale = convertDragEventToScaleMultiplier(e);
|
|
|
|
|
2024-01-20 23:29:26 +08:00
|
|
|
applyScale(shouldLockAspectRatio: e.ShiftPressed);
|
2024-01-20 07:22:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
protected override bool OnKeyDown(KeyDownEvent e)
|
|
|
|
{
|
|
|
|
if (IsDragged && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight))
|
|
|
|
{
|
2024-01-20 23:29:26 +08:00
|
|
|
applyScale(shouldLockAspectRatio: true);
|
2024-01-20 07:22:53 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return base.OnKeyDown(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void OnKeyUp(KeyUpEvent e)
|
|
|
|
{
|
|
|
|
base.OnKeyUp(e);
|
|
|
|
|
|
|
|
if (IsDragged && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight))
|
2024-01-20 23:29:26 +08:00
|
|
|
applyScale(shouldLockAspectRatio: false);
|
2024-01-20 07:22:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
protected override void OnDragEnd(DragEndEvent e)
|
|
|
|
{
|
|
|
|
scaleHandler?.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
private Vector2 convertDragEventToScaleMultiplier(DragEvent e)
|
|
|
|
{
|
|
|
|
Vector2 scale = e.MousePosition - e.MouseDownPosition;
|
|
|
|
adjustScaleFromAnchor(ref scale);
|
2024-01-20 23:49:10 +08:00
|
|
|
|
|
|
|
var surroundingQuad = scaleHandler!.OriginalSurroundingQuad!.Value;
|
|
|
|
scale.X = Precision.AlmostEquals(surroundingQuad.Width, 0) ? 0 : scale.X / surroundingQuad.Width;
|
|
|
|
scale.Y = Precision.AlmostEquals(surroundingQuad.Height, 0) ? 0 : scale.Y / surroundingQuad.Height;
|
|
|
|
|
|
|
|
return scale + Vector2.One;
|
2024-01-20 07:22:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void adjustScaleFromAnchor(ref Vector2 scale)
|
|
|
|
{
|
|
|
|
// cancel out scale in axes we don't care about (based on which drag handle was used).
|
2024-01-20 22:12:48 +08:00
|
|
|
if ((originalAnchor & Anchor.x1) > 0) scale.X = 0;
|
|
|
|
if ((originalAnchor & Anchor.y1) > 0) scale.Y = 0;
|
2024-01-20 07:22:53 +08:00
|
|
|
|
|
|
|
// reverse the scale direction if dragging from top or left.
|
2024-01-20 20:04:05 +08:00
|
|
|
if ((originalAnchor & Anchor.x0) > 0) scale.X = -scale.X;
|
|
|
|
if ((originalAnchor & Anchor.y0) > 0) scale.Y = -scale.Y;
|
2024-01-20 07:22:53 +08:00
|
|
|
}
|
|
|
|
|
2024-01-20 23:29:26 +08:00
|
|
|
private void applyScale(bool shouldLockAspectRatio)
|
2024-01-20 07:22:53 +08:00
|
|
|
{
|
2024-01-20 23:29:26 +08:00
|
|
|
var newScale = shouldLockAspectRatio
|
2024-01-20 22:11:35 +08:00
|
|
|
? new Vector2((rawScale.X + rawScale.Y) * 0.5f)
|
2024-01-20 07:22:53 +08:00
|
|
|
: rawScale;
|
|
|
|
|
2024-01-20 22:39:38 +08:00
|
|
|
scaleHandler!.Update(newScale, getOriginPosition(), getAdjustAxis());
|
|
|
|
}
|
|
|
|
|
|
|
|
private Vector2 getOriginPosition()
|
|
|
|
{
|
|
|
|
var quad = scaleHandler!.OriginalSurroundingQuad!.Value;
|
|
|
|
Vector2 origin = quad.TopLeft;
|
|
|
|
|
|
|
|
if ((originalAnchor & Anchor.x0) > 0)
|
|
|
|
origin.X += quad.Width;
|
|
|
|
|
|
|
|
if ((originalAnchor & Anchor.y0) > 0)
|
|
|
|
origin.Y += quad.Height;
|
|
|
|
|
|
|
|
return origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Axes getAdjustAxis()
|
|
|
|
{
|
|
|
|
switch (originalAnchor)
|
|
|
|
{
|
|
|
|
case Anchor.TopCentre:
|
|
|
|
case Anchor.BottomCentre:
|
|
|
|
return Axes.Y;
|
|
|
|
|
|
|
|
case Anchor.CentreLeft:
|
|
|
|
case Anchor.CentreRight:
|
|
|
|
return Axes.X;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return Axes.Both;
|
|
|
|
}
|
2022-01-09 00:19:52 +08:00
|
|
|
}
|
2021-04-24 12:44:33 +08:00
|
|
|
}
|
|
|
|
}
|