Fix drag breaking if scrolling while dragging

This commit is contained in:
smoogipoo
2018-11-26 16:08:56 +09:00
parent 60ffad169f
commit f9f300b215
6 changed files with 69 additions and 13 deletions

View File

@ -3,6 +3,7 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
@ -14,6 +15,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class ManiaSelectionBlueprint : SelectionBlueprint public class ManiaSelectionBlueprint : SelectionBlueprint
{ {
public Vector2 ScreenSpaceMouseDownPosition { get; private set; }
public Vector2 MouseDownPosition { get; private set; }
protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject; protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject;
protected IClock EditorClock { get; private set; } protected IClock EditorClock { get; private set; }
@ -43,6 +47,24 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
Position = Parent.ToLocalSpace(HitObject.ToScreenSpace(Vector2.Zero)); 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() public override void Show()
{ {
HitObject.AlwaysAlive = true; HitObject.AlwaysAlive = true;

View File

@ -5,6 +5,8 @@ using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Timing; 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.Mania.Objects;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
@ -29,11 +31,42 @@ namespace osu.Game.Rulesets.Mania.Edit
editorClock = clock; 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);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="reference">The <see cref="ManiaSelectionBlueprint"/> that received the drag event.</param>
private void adjustOrigins(ManiaSelectionBlueprint reference)
{ {
var hitObject = blueprint.HitObject; 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<ManiaSelectionBlueprint>())
b.HitObject.Y += movementDelta;
}
private void performDragMovement(DragEvent dragEvent)
{
foreach (var b in SelectedBlueprints)
{
var hitObject = b.HitObject;
var objectParent = (HitObjectContainer)hitObject.Parent; var objectParent = (HitObjectContainer)hitObject.Parent;
@ -59,11 +92,9 @@ namespace osu.Game.Rulesets.Mania.Edit
objectParent.Add(hitObject); objectParent.Add(hitObject);
} }
adjustColumn(dragEvent);
} }
private void adjustColumn(DragEvent dragEvent) private void performColumnMovement(DragEvent dragEvent)
{ {
var lastColumn = composer.ColumnAt(dragEvent.ScreenSpaceLastMousePosition); var lastColumn = composer.ColumnAt(dragEvent.ScreenSpaceLastMousePosition);
var currentColumn = composer.ColumnAt(dragEvent.ScreenSpaceMousePosition); var currentColumn = composer.ColumnAt(dragEvent.ScreenSpaceMousePosition);

View File

@ -3,6 +3,7 @@
using System.Linq; using System.Linq;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Screens.Edit.Compose.Components;
@ -10,10 +11,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{ {
public class OsuSelectionHandler : SelectionHandler 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<OsuHitObject>()) foreach (var h in SelectedHitObjects.OfType<OsuHitObject>())
{ {
if (h is Spinner) if (h is Spinner)
@ -24,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Edit
h.Position += dragEvent.Delta; h.Position += dragEvent.Delta;
} }
base.HandleDrag(blueprint, dragEvent);
} }
} }
} }

View File

@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit
/// <summary> /// <summary>
/// Invoked when this <see cref="SelectionBlueprint"/> has requested drag. /// Invoked when this <see cref="SelectionBlueprint"/> has requested drag.
/// </summary> /// </summary>
public event Action<DragEvent> DragRequested; public event Action<SelectionBlueprint, DragEvent> DragRequested;
/// <summary> /// <summary>
/// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to. /// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to.
@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Edit
protected override bool OnDrag(DragEvent e) protected override bool OnDrag(DragEvent e)
{ {
DragRequested?.Invoke(e); DragRequested?.Invoke(this, e);
return true; return true;
} }

View File

@ -180,7 +180,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionHandler.HandleSelectionRequested(blueprint, state); 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<SelectionBlueprint> private class SelectionBlueprintContainer : Container<SelectionBlueprint>
{ {

View File

@ -13,6 +13,7 @@ using osu.Framework.Input.States;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK; using osuTK;
using osuTK.Input; using osuTK.Input;
@ -66,8 +67,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// <summary> /// <summary>
/// Handles the selected <see cref="DrawableHitObject"/>s being dragged. /// Handles the selected <see cref="DrawableHitObject"/>s being dragged.
/// </summary> /// </summary>
/// <param name="blueprint">The <see cref="SelectionBlueprint"/> that received the drag event.</param>
/// <param name="dragEvent">The drag event.</param> /// <param name="dragEvent">The drag event.</param>
public virtual void HandleDrag(DragEvent dragEvent) public virtual void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent)
{ {
} }