1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:22:55 +08:00

Allow dragging anywhere in a capture box to move objects

This commit is contained in:
smoogipoo 2018-03-09 23:43:50 +09:00
parent 4a48136e4f
commit ad72d3816b
5 changed files with 53 additions and 33 deletions

View File

@ -108,6 +108,7 @@ namespace osu.Game.Rulesets.Edit
selectionLayer.ObjectSelected += hitObjectOverlayLayer.AddOverlay;
selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;
selectionLayer.SelectionMovementRequested += hitObjectOverlayLayer.MoveObjects;
toolboxCollection.Items =
new[] { new RadioButton("Select", () => setCompositionTool(null)) }

View File

@ -1,11 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
@ -17,6 +19,11 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
/// </summary>
public class CaptureBox : VisibilityContainer
{
/// <summary>
/// Invoked when the captured <see cref="DrawableHitObject"/>s should be moved.
/// </summary>
public event Action<Vector2> MovementRequested;
private readonly IDrawable captureArea;
private readonly IReadOnlyList<DrawableHitObject> capturedObjects;
@ -67,6 +74,18 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
Position = topLeft;
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;
protected override bool OnDragStart(InputState state) => true;
protected override bool OnDrag(InputState state)
{
MovementRequested?.Invoke(state.Mouse.Delta);
return true;
}
protected override bool OnDragEnd(InputState state) => true;
public override bool DisposeOnDeathRemoval => true;
protected override void PopIn() => this.FadeIn();

View File

@ -2,42 +2,17 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Game.Rulesets.Edit.Types;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Edit.Layers.Selection
{
public class HitObjectOverlay : OverlayContainer
public class HitObjectOverlay : Container
{
// ReSharper disable once NotAccessedField.Local
// This will be used later to handle drag movement, etc
private readonly DrawableHitObject hitObject;
public readonly DrawableHitObject HitObject;
public HitObjectOverlay(DrawableHitObject hitObject)
{
this.hitObject = hitObject;
State = Visibility.Visible;
HitObject = hitObject;
}
protected override bool OnDragStart(InputState state) => hitObject.HitObject is IHasEditablePosition;
protected override bool OnDrag(InputState state)
{
switch (hitObject.HitObject)
{
case IHasEditablePosition editablePosition:
editablePosition.SetPosition(state.Mouse.Delta);
break;
}
return true;
}
protected override bool OnDragEnd(InputState state) => true;
protected override void PopIn() => Alpha = 1;
protected override void PopOut() => Alpha = 0;
}
}

View File

@ -1,20 +1,25 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Game.Rulesets.Edit.Types;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
namespace osu.Game.Rulesets.Edit.Layers.Selection
{
public class HitObjectOverlayLayer : CompositeDrawable
{
private readonly Dictionary<DrawableHitObject, HitObjectOverlay> existingOverlays = new Dictionary<DrawableHitObject, HitObjectOverlay>();
private readonly Container<HitObjectOverlay> overlayContainer;
public HitObjectOverlayLayer()
{
RelativeSizeAxes = Axes.Both;
InternalChild = overlayContainer = new Container<HitObjectOverlay> { RelativeSizeAxes = Axes.Both };
}
/// <summary>
@ -27,8 +32,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
if (overlay == null)
return;
existingOverlays[hitObject] = overlay;
AddInternal(overlay);
overlayContainer.Add(overlay);
}
/// <summary>
@ -37,13 +41,28 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to remove the overlay for.</param>
public void RemoveOverlay(DrawableHitObject hitObject)
{
if (!existingOverlays.TryGetValue(hitObject, out var existing))
var existing = overlayContainer.FirstOrDefault(h => h.HitObject == hitObject);
if (existing == null)
return;
existing.Hide();
existing.Expire();
}
public void MoveObjects(Vector2 offset)
{
// Todo: Various forms of snapping
foreach (var hitObject in overlayContainer.Select(o => o.HitObject.HitObject))
{
switch (hitObject)
{
case IHasEditablePosition editablePosition:
editablePosition.SetPosition(offset);
break;
}
}
}
/// <summary>
/// Creates a <see cref="HitObjectOverlay"/> for a specific <see cref="DrawableHitObject"/>.
/// </summary>

View File

@ -27,6 +27,11 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
/// </summary>
public event Action<DrawableHitObject> ObjectDeselected;
/// <summary>
/// Invoked when the selected <see cref="DrawableHitObject"/>s should be moved.
/// </summary>
public event Action<Vector2> SelectionMovementRequested;
private readonly Playfield playfield;
public SelectionLayer(Playfield playfield)
@ -192,6 +197,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
return;
AddInternal(captureBox = new CaptureBox(this, selectedHitObjects.ToList()));
captureBox.MovementRequested += v => SelectionMovementRequested?.Invoke(v);
}
}
}