mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 02:42:54 +08:00
Move selection overlay to HitObjectOverlayLayer for extensibility
This commit is contained in:
parent
0e8fbc47b7
commit
4103c66cff
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
typeof(SelectionBox),
|
||||
typeof(SelectionLayer),
|
||||
typeof(CaptureBox),
|
||||
typeof(SelectionOverlay),
|
||||
typeof(HitObjectComposer),
|
||||
typeof(OsuHitObjectComposer),
|
||||
typeof(HitObjectOverlayLayer),
|
||||
|
@ -108,7 +108,8 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
selectionLayer.ObjectSelected += hitObjectOverlayLayer.AddOverlay;
|
||||
selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;
|
||||
selectionLayer.SelectionMovementRequested += hitObjectOverlayLayer.MoveObjects;
|
||||
selectionLayer.SelectionCleared += hitObjectOverlayLayer.RemoveSelectionOverlay;
|
||||
selectionLayer.SelectionFinished += hitObjectOverlayLayer.AddSelectionOverlay;
|
||||
|
||||
toolboxCollection.Items =
|
||||
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
||||
|
@ -1,11 +1,10 @@
|
||||
// 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;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
@ -48,18 +47,14 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
existing.Expire();
|
||||
}
|
||||
|
||||
public void MoveObjects(InputState state)
|
||||
private SelectionOverlay currentSelectionOverlay;
|
||||
|
||||
public void AddSelectionOverlay() => AddInternal(currentSelectionOverlay = CreateSelectionOverlay(overlayContainer));
|
||||
|
||||
public void RemoveSelectionOverlay()
|
||||
{
|
||||
// Todo: Various forms of snapping
|
||||
foreach (var hitObject in overlayContainer.Select(o => o.HitObject.HitObject))
|
||||
{
|
||||
switch (hitObject)
|
||||
{
|
||||
case IHasEditablePosition editablePosition:
|
||||
editablePosition.OffsetPosition(state.Mouse.Delta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentSelectionOverlay?.Hide();
|
||||
currentSelectionOverlay?.Expire();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -67,5 +62,12 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param>
|
||||
protected virtual HitObjectOverlay CreateOverlayFor(DrawableHitObject hitObject) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SelectionOverlay"/> which outlines <see cref="DrawableHitObject"/>s
|
||||
/// and handles all hitobject movement/pattern adjustments.
|
||||
/// </summary>
|
||||
/// <param name="overlays">The <see cref="DrawableHitObject"/> overlays.</param>
|
||||
protected virtual SelectionOverlay CreateSelectionOverlay(IReadOnlyList<HitObjectOverlay> overlays) => new SelectionOverlay(overlays);
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,14 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
public event Action<DrawableHitObject> ObjectDeselected;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the selected <see cref="DrawableHitObject"/>s should be moved.
|
||||
/// Invoked when the selection has been cleared.
|
||||
/// </summary>
|
||||
public event Action<InputState> SelectionMovementRequested;
|
||||
public event Action SelectionCleared;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the user has finished selecting all <see cref="DrawableHitObject"/>s.
|
||||
/// </summary>
|
||||
public event Action SelectionFinished;
|
||||
|
||||
private readonly Playfield playfield;
|
||||
|
||||
@ -42,7 +47,6 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
}
|
||||
|
||||
private SelectionBox selectionBox;
|
||||
private CaptureBox captureBox;
|
||||
|
||||
private readonly HashSet<DrawableHitObject> selectedHitObjects = new HashSet<DrawableHitObject>();
|
||||
|
||||
@ -100,7 +104,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
if (!select(hitObject))
|
||||
return;
|
||||
|
||||
clearCapture();
|
||||
clearSelection();
|
||||
finishSelection();
|
||||
}
|
||||
|
||||
@ -127,7 +131,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
if (!deselect(hitObject))
|
||||
return;
|
||||
|
||||
clearCapture();
|
||||
clearSelection();
|
||||
finishSelection();
|
||||
}
|
||||
|
||||
@ -153,7 +157,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
selectedHitObjects.ForEach(h => ObjectDeselected?.Invoke(h));
|
||||
selectedHitObjects.Clear();
|
||||
|
||||
clearCapture();
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -185,19 +189,13 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
select(target);
|
||||
}
|
||||
|
||||
private void clearCapture()
|
||||
{
|
||||
captureBox?.Hide();
|
||||
captureBox?.Expire();
|
||||
}
|
||||
private void clearSelection() => SelectionCleared?.Invoke();
|
||||
|
||||
private void finishSelection()
|
||||
{
|
||||
if (selectedHitObjects.Count == 0)
|
||||
return;
|
||||
|
||||
AddInternal(captureBox = new CaptureBox(this, selectedHitObjects.ToList()));
|
||||
captureBox.MovementRequested += v => SelectionMovementRequested?.Invoke(v);
|
||||
SelectionFinished?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
// 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 System.Linq;
|
||||
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.Edit.Types;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using OpenTK;
|
||||
|
||||
@ -17,20 +18,13 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
/// <summary>
|
||||
/// A box which encloses <see cref="DrawableHitObject"/>s.
|
||||
/// </summary>
|
||||
public class CaptureBox : VisibilityContainer
|
||||
public class SelectionOverlay : VisibilityContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the captured <see cref="DrawableHitObject"/>s should be moved.
|
||||
/// </summary>
|
||||
public event Action<InputState> MovementRequested;
|
||||
private readonly IReadOnlyList<HitObjectOverlay> overlays;
|
||||
|
||||
private readonly IDrawable captureArea;
|
||||
private readonly IReadOnlyList<DrawableHitObject> capturedObjects;
|
||||
|
||||
public CaptureBox(IDrawable captureArea, IReadOnlyList<DrawableHitObject> capturedObjects)
|
||||
public SelectionOverlay(IReadOnlyList<HitObjectOverlay> overlays)
|
||||
{
|
||||
this.captureArea = captureArea;
|
||||
this.capturedObjects = capturedObjects;
|
||||
this.overlays = overlays;
|
||||
|
||||
Masking = true;
|
||||
BorderThickness = SelectionBox.BORDER_RADIUS;
|
||||
@ -61,10 +55,10 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
var topLeft = new Vector2(float.MaxValue, float.MaxValue);
|
||||
var bottomRight = new Vector2(float.MinValue, float.MinValue);
|
||||
|
||||
foreach (var obj in capturedObjects)
|
||||
foreach (var obj in overlays)
|
||||
{
|
||||
topLeft = Vector2.ComponentMin(topLeft, captureArea.ToLocalSpace(obj.SelectionQuad.TopLeft));
|
||||
bottomRight = Vector2.ComponentMax(bottomRight, captureArea.ToLocalSpace(obj.SelectionQuad.BottomRight));
|
||||
topLeft = Vector2.ComponentMin(topLeft, Parent.ToLocalSpace(obj.HitObject.SelectionQuad.TopLeft));
|
||||
bottomRight = Vector2.ComponentMax(bottomRight, Parent.ToLocalSpace(obj.HitObject.SelectionQuad.BottomRight));
|
||||
}
|
||||
|
||||
topLeft -= new Vector2(5);
|
||||
@ -80,7 +74,16 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||
|
||||
protected override bool OnDrag(InputState state)
|
||||
{
|
||||
MovementRequested?.Invoke(state);
|
||||
// Todo: Various forms of snapping
|
||||
foreach (var hitObject in overlays.Select(o => o.HitObject.HitObject))
|
||||
{
|
||||
switch (hitObject)
|
||||
{
|
||||
case IHasEditablePosition editablePosition:
|
||||
editablePosition.OffsetPosition(state.Mouse.Delta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -362,7 +362,7 @@
|
||||
<Compile Include="Rulesets\Configuration\IRulesetConfigManager.cs" />
|
||||
<Compile Include="Rulesets\Configuration\RulesetConfigManager.cs" />
|
||||
<Compile Include="Rulesets\Edit\Layers\BorderLayer.cs" />
|
||||
<Compile Include="Rulesets\Edit\Layers\Selection\CaptureBox.cs" />
|
||||
<Compile Include="Rulesets\Edit\Layers\Selection\SelectionOverlay.cs" />
|
||||
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlay.cs" />
|
||||
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlayLayer.cs" />
|
||||
<Compile Include="Rulesets\Edit\Types\IHasEditablePosition.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user