From 39b55a85df11a2dc36257990d176245ebb9d2500 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Sep 2020 13:52:57 +0900 Subject: [PATCH] Move a lot of the implementation to base SelectionHandler --- .../Edit/OsuSelectionHandler.cs | 56 +++++++++------- .../Compose/Components/SelectionHandler.cs | 67 ++++++++++++++++++- 2 files changed, 94 insertions(+), 29 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index c7be921a4e..a2642bda83 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -5,7 +5,6 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; -using osu.Framework.Input.Events; using osu.Framework.Utils; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; @@ -16,24 +15,22 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuSelectionHandler : SelectionHandler { - public override ComposeSelectionBox CreateSelectionBox() - => new ComposeSelectionBox - { - CanRotate = true, - CanScaleX = true, - CanScaleY = true, + protected override void OnSelectionChanged() + { + base.OnSelectionChanged(); - OperationStarted = () => ChangeHandler.BeginChange(), - OperationEnded = () => - { - ChangeHandler.EndChange(); - referenceOrigin = null; - }, + bool canOperate = SelectedHitObjects.Count() > 1 || SelectedHitObjects.Any(s => s is Slider); - OnRotation = e => rotateSelection(e.Delta.X), - OnScaleX = handleScaleX, - OnScaleY = handleScaleY, - }; + SelectionBox.CanRotate = canOperate; + SelectionBox.CanScaleX = canOperate; + SelectionBox.CanScaleY = canOperate; + } + + protected override void OnDragOperationEnded() + { + base.OnDragOperationEnded(); + referenceOrigin = null; + } public override bool HandleMovement(MoveSelectionEvent moveEvent) => moveSelection(moveEvent.InstantDelta); @@ -43,35 +40,35 @@ public override bool HandleMovement(MoveSelectionEvent moveEvent) => /// 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; if (direction < 0) { // when resizing from a top drag handle, we want to move the selection first - if (!moveSelection(new Vector2(0, e.Delta.Y))) - return; + if (!moveSelection(new Vector2(0, scale))) + 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; if (direction < 0) { // when resizing from a left drag handle, we want to move the selection first - if (!moveSelection(new Vector2(e.Delta.X, 0))) - return; + if (!moveSelection(new Vector2(scale, 0))) + 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(); @@ -96,6 +93,7 @@ private bool rotateSelection(in float delta) } } + // todo: not always return true; } @@ -161,8 +159,14 @@ private bool moveSelection(Vector2 delta) return true; } + /// + /// Returns a gamefield-space quad surrounding the current selection. + /// private Quad getSelectionQuad() { + if (!SelectedHitObjects.Any()) + return new Quad(); + Vector2 minPosition = new Vector2(float.MaxValue, float.MaxValue); Vector2 maxPosition = new Vector2(float.MinValue, float.MinValue); diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index afaa5b0f3d..6cd503b580 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -43,6 +43,8 @@ public class SelectionHandler : CompositeDrawable, IKeyBindingHandler 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), + }; + + /// + /// Fired when a drag operation ends from the selection box. + /// + protected virtual void OnDragOperationBegan() + { + ChangeHandler.BeginChange(); + } + + /// + /// Fired when a drag operation begins from the selection box. + /// + protected virtual void OnDragOperationEnded() + { + ChangeHandler.EndChange(); + } #region User Input Handling @@ -108,7 +135,30 @@ private void load(OsuColour colours) /// Whether any s could be moved. /// Returning true will also propagate StartTime changes provided by the closest . /// - public virtual bool HandleMovement(MoveSelectionEvent moveEvent) => true; + public virtual bool HandleMovement(MoveSelectionEvent moveEvent) => false; + + /// + /// Handles the selected s being rotated. + /// + /// The delta angle to apply to the selection. + /// Whether any s could be moved. + public virtual bool HandleRotation(float angle) => false; + + /// + /// Handles the selected s being scaled in a vertical 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 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 bool OnPressed(PlatformAction action) { @@ -211,11 +261,22 @@ internal void UpdateVisibility() selectionDetailsText.Text = count > 0 ? count.ToString() : string.Empty; if (count > 0) + { Show(); + OnSelectionChanged(); + } else Hide(); } + /// + /// Triggered whenever more than one object is selected, on each change. + /// Should update the selection box's state to match supported operations. + /// + protected virtual void OnSelectionChanged() + { + } + protected override void Update() { base.Update();