From f9f300b215d07f3859bc32f73f6ad2981e0f1f33 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 26 Nov 2018 16:08:56 +0900 Subject: [PATCH] Fix drag breaking if scrolling while dragging --- .../Blueprints/ManiaSelectionBlueprint.cs | 22 ++++++++++ .../Edit/ManiaSelectionHandler.cs | 43 ++++++++++++++++--- .../Edit/OsuSelectionHandler.cs | 7 +-- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 4 +- .../Compose/Components/BlueprintContainer.cs | 2 +- .../Compose/Components/SelectionHandler.cs | 4 +- 6 files changed, 69 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs index fc0180069d..df229b23ae 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mania.Objects.Drawables; @@ -14,6 +15,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints { public class ManiaSelectionBlueprint : SelectionBlueprint { + public Vector2 ScreenSpaceMouseDownPosition { get; private set; } + public Vector2 MouseDownPosition { get; private set; } + protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject; protected IClock EditorClock { get; private set; } @@ -43,6 +47,24 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints Position = Parent.ToLocalSpace(HitObject.ToScreenSpace(Vector2.Zero)); } + protected override bool OnMouseDown(MouseDownEvent e) + { + ScreenSpaceMouseDownPosition = e.ScreenSpaceMousePosition; + MouseDownPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition); + + return base.OnMouseDown(e); + } + + protected override bool OnDrag(DragEvent e) + { + var result = base.OnDrag(e); + + ScreenSpaceMouseDownPosition = e.ScreenSpaceMousePosition; + MouseDownPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition); + + return result; + } + public override void Show() { HitObject.AlwaysAlive = true; diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs index 4cb417a32e..1d6b9d6c69 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs @@ -5,6 +5,8 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Input.Events; using osu.Framework.Timing; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mania.Edit.Blueprints; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; @@ -29,11 +31,42 @@ namespace osu.Game.Rulesets.Mania.Edit editorClock = clock; } - public override void HandleDrag(DragEvent dragEvent) + public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent) { - foreach (var blueprint in SelectedBlueprints) + adjustOrigins((ManiaSelectionBlueprint)blueprint); + performDragMovement(dragEvent); + performColumnMovement(dragEvent); + + base.HandleDrag(blueprint, dragEvent); + } + + /// + /// Ensures that the position of hitobjects remains centred to the mouse position. + /// E.g. The hitobject position will change if the editor scrolls while a hitobject is dragged. + /// + /// The that received the drag event. + private void adjustOrigins(ManiaSelectionBlueprint reference) + { + var referenceParent = (HitObjectContainer)reference.HitObject.Parent; + + float offsetFromReferenceOrigin = reference.MouseDownPosition.Y - reference.HitObject.OriginPosition.Y; + float targetPosition = referenceParent.ToLocalSpace(reference.ScreenSpaceMouseDownPosition).Y - offsetFromReferenceOrigin; + + // Flip the vertical coordinate space when scrolling downwards + if (scrollingInfo.Direction.Value == ScrollingDirection.Down) + targetPosition = targetPosition - referenceParent.DrawHeight; + + float movementDelta = targetPosition - reference.HitObject.Position.Y; + + foreach (var b in SelectedBlueprints.OfType()) + b.HitObject.Y += movementDelta; + } + + private void performDragMovement(DragEvent dragEvent) + { + foreach (var b in SelectedBlueprints) { - var hitObject = blueprint.HitObject; + var hitObject = b.HitObject; var objectParent = (HitObjectContainer)hitObject.Parent; @@ -59,11 +92,9 @@ namespace osu.Game.Rulesets.Mania.Edit objectParent.Add(hitObject); } - - adjustColumn(dragEvent); } - private void adjustColumn(DragEvent dragEvent) + private void performColumnMovement(DragEvent dragEvent) { var lastColumn = composer.ColumnAt(dragEvent.ScreenSpaceLastMousePosition); var currentColumn = composer.ColumnAt(dragEvent.ScreenSpaceMousePosition); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 54f629cbea..0c7e571ef5 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -3,6 +3,7 @@ using System.Linq; using osu.Framework.Input.Events; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit.Compose.Components; @@ -10,10 +11,8 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuSelectionHandler : SelectionHandler { - public override void HandleDrag(DragEvent dragEvent) + public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent) { - base.HandleDrag(dragEvent); - foreach (var h in SelectedHitObjects.OfType()) { if (h is Spinner) @@ -24,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Edit h.Position += dragEvent.Delta; } + + base.HandleDrag(blueprint, dragEvent); } } } diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 04e8834946..ec4df01e55 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit /// /// Invoked when this has requested drag. /// - public event Action DragRequested; + public event Action DragRequested; /// /// The which this applies to. @@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Edit protected override bool OnDrag(DragEvent e) { - DragRequested?.Invoke(e); + DragRequested?.Invoke(this, e); return true; } diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 4664d521ec..80bfe21367 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -180,7 +180,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionHandler.HandleSelectionRequested(blueprint, state); - private void onDragRequested(DragEvent dragEvent) => selectionHandler.HandleDrag(dragEvent); + private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent) => selectionHandler.HandleDrag(blueprint, dragEvent); private class SelectionBlueprintContainer : Container { diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 0140f3aa75..f8ceeedba9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -13,6 +13,7 @@ using osu.Framework.Input.States; using osu.Game.Graphics; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Input; @@ -66,8 +67,9 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Handles the selected s being dragged. /// + /// The that received the drag event. /// The drag event. - public virtual void HandleDrag(DragEvent dragEvent) + public virtual void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent) { }