Move a lot of the implementation to base SelectionHandler

This commit is contained in:
Dean Herbert
2020-09-30 13:52:57 +09:00
parent f2c26c0927
commit 39b55a85df
2 changed files with 94 additions and 29 deletions

View File

@ -5,7 +5,6 @@ using System;
using System.Linq; using System.Linq;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Input.Events;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
@ -16,24 +15,22 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
public class OsuSelectionHandler : SelectionHandler public class OsuSelectionHandler : SelectionHandler
{ {
public override ComposeSelectionBox CreateSelectionBox() protected override void OnSelectionChanged()
=> new ComposeSelectionBox
{ {
CanRotate = true, base.OnSelectionChanged();
CanScaleX = true,
CanScaleY = true,
OperationStarted = () => ChangeHandler.BeginChange(), bool canOperate = SelectedHitObjects.Count() > 1 || SelectedHitObjects.Any(s => s is Slider);
OperationEnded = () =>
SelectionBox.CanRotate = canOperate;
SelectionBox.CanScaleX = canOperate;
SelectionBox.CanScaleY = canOperate;
}
protected override void OnDragOperationEnded()
{ {
ChangeHandler.EndChange(); base.OnDragOperationEnded();
referenceOrigin = null; referenceOrigin = null;
}, }
OnRotation = e => rotateSelection(e.Delta.X),
OnScaleX = handleScaleX,
OnScaleY = handleScaleY,
};
public override bool HandleMovement(MoveSelectionEvent moveEvent) => public override bool HandleMovement(MoveSelectionEvent moveEvent) =>
moveSelection(moveEvent.InstantDelta); moveSelection(moveEvent.InstantDelta);
@ -43,35 +40,35 @@ namespace osu.Game.Rulesets.Osu.Edit
/// </summary> /// </summary>
private Vector2? referenceOrigin; private Vector2? referenceOrigin;
private void handleScaleY(DragEvent e, Anchor reference) public override bool HandleScaleY(in float scale, Anchor reference)
{ {
int direction = (reference & Anchor.y0) > 0 ? -1 : 1; int direction = (reference & Anchor.y0) > 0 ? -1 : 1;
if (direction < 0) if (direction < 0)
{ {
// when resizing from a top drag handle, we want to move the selection first // when resizing from a top drag handle, we want to move the selection first
if (!moveSelection(new Vector2(0, e.Delta.Y))) if (!moveSelection(new Vector2(0, scale)))
return; return false;
} }
scaleSelection(new Vector2(0, direction * e.Delta.Y)); return scaleSelection(new Vector2(0, direction * scale));
} }
private void handleScaleX(DragEvent e, Anchor reference) public override bool HandleScaleX(in float scale, Anchor reference)
{ {
int direction = (reference & Anchor.x0) > 0 ? -1 : 1; int direction = (reference & Anchor.x0) > 0 ? -1 : 1;
if (direction < 0) if (direction < 0)
{ {
// when resizing from a left drag handle, we want to move the selection first // when resizing from a left drag handle, we want to move the selection first
if (!moveSelection(new Vector2(e.Delta.X, 0))) if (!moveSelection(new Vector2(scale, 0)))
return; return false;
} }
scaleSelection(new Vector2(direction * e.Delta.X, 0)); return scaleSelection(new Vector2(direction * scale, 0));
} }
private bool rotateSelection(in float delta) public override bool HandleRotation(float delta)
{ {
Quad quad = getSelectionQuad(); Quad quad = getSelectionQuad();
@ -96,6 +93,7 @@ namespace osu.Game.Rulesets.Osu.Edit
} }
} }
// todo: not always
return true; return true;
} }
@ -161,8 +159,14 @@ namespace osu.Game.Rulesets.Osu.Edit
return true; return true;
} }
/// <summary>
/// Returns a gamefield-space quad surrounding the current selection.
/// </summary>
private Quad getSelectionQuad() private Quad getSelectionQuad()
{ {
if (!SelectedHitObjects.Any())
return new Quad();
Vector2 minPosition = new Vector2(float.MaxValue, float.MaxValue); Vector2 minPosition = new Vector2(float.MaxValue, float.MaxValue);
Vector2 maxPosition = new Vector2(float.MinValue, float.MinValue); Vector2 maxPosition = new Vector2(float.MinValue, float.MinValue);

View File

@ -43,6 +43,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
private OsuSpriteText selectionDetailsText; private OsuSpriteText selectionDetailsText;
protected ComposeSelectionBox SelectionBox { get; private set; }
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
protected EditorBeatmap EditorBeatmap { get; private set; } protected EditorBeatmap EditorBeatmap { get; private set; }
@ -87,12 +89,37 @@ namespace osu.Game.Screens.Edit.Compose.Components
} }
} }
}, },
CreateSelectionBox(), SelectionBox = CreateSelectionBox(),
} }
}; };
} }
public virtual ComposeSelectionBox CreateSelectionBox() => new ComposeSelectionBox(); public ComposeSelectionBox CreateSelectionBox()
=> new ComposeSelectionBox
{
OperationStarted = OnDragOperationBegan,
OperationEnded = OnDragOperationEnded,
OnRotation = e => HandleRotation(e.Delta.X),
OnScaleX = (e, anchor) => HandleScaleX(e.Delta.X, anchor),
OnScaleY = (e, anchor) => HandleScaleY(e.Delta.Y, anchor),
};
/// <summary>
/// Fired when a drag operation ends from the selection box.
/// </summary>
protected virtual void OnDragOperationBegan()
{
ChangeHandler.BeginChange();
}
/// <summary>
/// Fired when a drag operation begins from the selection box.
/// </summary>
protected virtual void OnDragOperationEnded()
{
ChangeHandler.EndChange();
}
#region User Input Handling #region User Input Handling
@ -108,7 +135,30 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// Whether any <see cref="DrawableHitObject"/>s could be moved. /// Whether any <see cref="DrawableHitObject"/>s could be moved.
/// Returning true will also propagate StartTime changes provided by the closest <see cref="IPositionSnapProvider.SnapScreenSpacePositionToValidTime"/>. /// Returning true will also propagate StartTime changes provided by the closest <see cref="IPositionSnapProvider.SnapScreenSpacePositionToValidTime"/>.
/// </returns> /// </returns>
public virtual bool HandleMovement(MoveSelectionEvent moveEvent) => true; public virtual bool HandleMovement(MoveSelectionEvent moveEvent) => false;
/// <summary>
/// Handles the selected <see cref="DrawableHitObject"/>s being rotated.
/// </summary>
/// <param name="angle">The delta angle to apply to the selection.</param>
/// <returns>Whether any <see cref="DrawableHitObject"/>s could be moved.</returns>
public virtual bool HandleRotation(float angle) => false;
/// <summary>
/// Handles the selected <see cref="DrawableHitObject"/>s being scaled in a vertical direction.
/// </summary>
/// <param name="scale">The delta scale to apply.</param>
/// <param name="anchor">The point of reference where the scale is originating from.</param>
/// <returns>Whether any <see cref="DrawableHitObject"/>s could be moved.</returns>
public virtual bool HandleScaleY(in float scale, Anchor anchor) => false;
/// <summary>
/// Handles the selected <see cref="DrawableHitObject"/>s being scaled in a horizontal direction.
/// </summary>
/// <param name="scale">The delta scale to apply.</param>
/// <param name="anchor">The point of reference where the scale is originating from.</param>
/// <returns>Whether any <see cref="DrawableHitObject"/>s could be moved.</returns>
public virtual bool HandleScaleX(in float scale, Anchor anchor) => false;
public bool OnPressed(PlatformAction action) public bool OnPressed(PlatformAction action)
{ {
@ -211,11 +261,22 @@ namespace osu.Game.Screens.Edit.Compose.Components
selectionDetailsText.Text = count > 0 ? count.ToString() : string.Empty; selectionDetailsText.Text = count > 0 ? count.ToString() : string.Empty;
if (count > 0) if (count > 0)
{
Show(); Show();
OnSelectionChanged();
}
else else
Hide(); Hide();
} }
/// <summary>
/// Triggered whenever more than one object is selected, on each change.
/// Should update the selection box's state to match supported operations.
/// </summary>
protected virtual void OnSelectionChanged()
{
}
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();