diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e6a51cc39b..383adca136 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -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)) } diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/CaptureBox.cs b/osu.Game/Rulesets/Edit/Layers/Selection/CaptureBox.cs index 6702678448..1454c78014 100644 --- a/osu.Game/Rulesets/Edit/Layers/Selection/CaptureBox.cs +++ b/osu.Game/Rulesets/Edit/Layers/Selection/CaptureBox.cs @@ -1,11 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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 /// public class CaptureBox : VisibilityContainer { + /// + /// Invoked when the captured s should be moved. + /// + public event Action MovementRequested; + private readonly IDrawable captureArea; private readonly IReadOnlyList 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(); diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs index 803e86ae77..8c58275943 100644 --- a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs +++ b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlay.cs @@ -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; } } diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs index 0b6e63d1fe..bb8496e9c6 100644 --- a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs +++ b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectOverlayLayer.cs @@ -1,20 +1,25 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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 existingOverlays = new Dictionary(); + private readonly Container overlayContainer; public HitObjectOverlayLayer() { RelativeSizeAxes = Axes.Both; + + InternalChild = overlayContainer = new Container { RelativeSizeAxes = Axes.Both }; } /// @@ -27,8 +32,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection if (overlay == null) return; - existingOverlays[hitObject] = overlay; - AddInternal(overlay); + overlayContainer.Add(overlay); } /// @@ -37,13 +41,28 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection /// The to remove the overlay for. 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; + } + } + } + /// /// Creates a for a specific . /// diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs b/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs index 3895d34d7f..0383b933ab 100644 --- a/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs +++ b/osu.Game/Rulesets/Edit/Layers/Selection/SelectionLayer.cs @@ -27,6 +27,11 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection /// public event Action ObjectDeselected; + /// + /// Invoked when the selected s should be moved. + /// + public event Action 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); } } }