mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 15:33:05 +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(SelectionBox),
|
||||||
typeof(SelectionLayer),
|
typeof(SelectionLayer),
|
||||||
typeof(CaptureBox),
|
typeof(SelectionOverlay),
|
||||||
typeof(HitObjectComposer),
|
typeof(HitObjectComposer),
|
||||||
typeof(OsuHitObjectComposer),
|
typeof(OsuHitObjectComposer),
|
||||||
typeof(HitObjectOverlayLayer),
|
typeof(HitObjectOverlayLayer),
|
||||||
|
@ -108,7 +108,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
selectionLayer.ObjectSelected += hitObjectOverlayLayer.AddOverlay;
|
selectionLayer.ObjectSelected += hitObjectOverlayLayer.AddOverlay;
|
||||||
selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;
|
selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;
|
||||||
selectionLayer.SelectionMovementRequested += hitObjectOverlayLayer.MoveObjects;
|
selectionLayer.SelectionCleared += hitObjectOverlayLayer.RemoveSelectionOverlay;
|
||||||
|
selectionLayer.SelectionFinished += hitObjectOverlayLayer.AddSelectionOverlay;
|
||||||
|
|
||||||
toolboxCollection.Items =
|
toolboxCollection.Items =
|
||||||
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input;
|
|
||||||
using osu.Game.Rulesets.Edit.Types;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Layers.Selection
|
namespace osu.Game.Rulesets.Edit.Layers.Selection
|
||||||
@ -48,18 +47,14 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
existing.Expire();
|
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
|
currentSelectionOverlay?.Hide();
|
||||||
foreach (var hitObject in overlayContainer.Select(o => o.HitObject.HitObject))
|
currentSelectionOverlay?.Expire();
|
||||||
{
|
|
||||||
switch (hitObject)
|
|
||||||
{
|
|
||||||
case IHasEditablePosition editablePosition:
|
|
||||||
editablePosition.OffsetPosition(state.Mouse.Delta);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -67,5 +62,12 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param>
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param>
|
||||||
protected virtual HitObjectOverlay CreateOverlayFor(DrawableHitObject hitObject) => null;
|
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;
|
public event Action<DrawableHitObject> ObjectDeselected;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the selected <see cref="DrawableHitObject"/>s should be moved.
|
/// Invoked when the selection has been cleared.
|
||||||
/// </summary>
|
/// </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;
|
private readonly Playfield playfield;
|
||||||
|
|
||||||
@ -42,7 +47,6 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SelectionBox selectionBox;
|
private SelectionBox selectionBox;
|
||||||
private CaptureBox captureBox;
|
|
||||||
|
|
||||||
private readonly HashSet<DrawableHitObject> selectedHitObjects = new HashSet<DrawableHitObject>();
|
private readonly HashSet<DrawableHitObject> selectedHitObjects = new HashSet<DrawableHitObject>();
|
||||||
|
|
||||||
@ -100,7 +104,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
if (!select(hitObject))
|
if (!select(hitObject))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clearCapture();
|
clearSelection();
|
||||||
finishSelection();
|
finishSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +131,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
if (!deselect(hitObject))
|
if (!deselect(hitObject))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clearCapture();
|
clearSelection();
|
||||||
finishSelection();
|
finishSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +157,7 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
selectedHitObjects.ForEach(h => ObjectDeselected?.Invoke(h));
|
selectedHitObjects.ForEach(h => ObjectDeselected?.Invoke(h));
|
||||||
selectedHitObjects.Clear();
|
selectedHitObjects.Clear();
|
||||||
|
|
||||||
clearCapture();
|
clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -185,19 +189,13 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
select(target);
|
select(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearCapture()
|
private void clearSelection() => SelectionCleared?.Invoke();
|
||||||
{
|
|
||||||
captureBox?.Hide();
|
|
||||||
captureBox?.Expire();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void finishSelection()
|
private void finishSelection()
|
||||||
{
|
{
|
||||||
if (selectedHitObjects.Count == 0)
|
if (selectedHitObjects.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
SelectionFinished?.Invoke();
|
||||||
AddInternal(captureBox = new CaptureBox(this, selectedHitObjects.ToList()));
|
|
||||||
captureBox.MovementRequested += v => SelectionMovementRequested?.Invoke(v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit.Types;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
@ -17,20 +18,13 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A box which encloses <see cref="DrawableHitObject"/>s.
|
/// A box which encloses <see cref="DrawableHitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CaptureBox : VisibilityContainer
|
public class SelectionOverlay : VisibilityContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
private readonly IReadOnlyList<HitObjectOverlay> overlays;
|
||||||
/// Invoked when the captured <see cref="DrawableHitObject"/>s should be moved.
|
|
||||||
/// </summary>
|
|
||||||
public event Action<InputState> MovementRequested;
|
|
||||||
|
|
||||||
private readonly IDrawable captureArea;
|
public SelectionOverlay(IReadOnlyList<HitObjectOverlay> overlays)
|
||||||
private readonly IReadOnlyList<DrawableHitObject> capturedObjects;
|
|
||||||
|
|
||||||
public CaptureBox(IDrawable captureArea, IReadOnlyList<DrawableHitObject> capturedObjects)
|
|
||||||
{
|
{
|
||||||
this.captureArea = captureArea;
|
this.overlays = overlays;
|
||||||
this.capturedObjects = capturedObjects;
|
|
||||||
|
|
||||||
Masking = true;
|
Masking = true;
|
||||||
BorderThickness = SelectionBox.BORDER_RADIUS;
|
BorderThickness = SelectionBox.BORDER_RADIUS;
|
||||||
@ -61,10 +55,10 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
var topLeft = new Vector2(float.MaxValue, float.MaxValue);
|
var topLeft = new Vector2(float.MaxValue, float.MaxValue);
|
||||||
var bottomRight = new Vector2(float.MinValue, float.MinValue);
|
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));
|
topLeft = Vector2.ComponentMin(topLeft, Parent.ToLocalSpace(obj.HitObject.SelectionQuad.TopLeft));
|
||||||
bottomRight = Vector2.ComponentMax(bottomRight, captureArea.ToLocalSpace(obj.SelectionQuad.BottomRight));
|
bottomRight = Vector2.ComponentMax(bottomRight, Parent.ToLocalSpace(obj.HitObject.SelectionQuad.BottomRight));
|
||||||
}
|
}
|
||||||
|
|
||||||
topLeft -= new Vector2(5);
|
topLeft -= new Vector2(5);
|
||||||
@ -80,7 +74,16 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
|
|||||||
|
|
||||||
protected override bool OnDrag(InputState state)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -362,7 +362,7 @@
|
|||||||
<Compile Include="Rulesets\Configuration\IRulesetConfigManager.cs" />
|
<Compile Include="Rulesets\Configuration\IRulesetConfigManager.cs" />
|
||||||
<Compile Include="Rulesets\Configuration\RulesetConfigManager.cs" />
|
<Compile Include="Rulesets\Configuration\RulesetConfigManager.cs" />
|
||||||
<Compile Include="Rulesets\Edit\Layers\BorderLayer.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\HitObjectOverlay.cs" />
|
||||||
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlayLayer.cs" />
|
<Compile Include="Rulesets\Edit\Layers\Selection\HitObjectOverlayLayer.cs" />
|
||||||
<Compile Include="Rulesets\Edit\Types\IHasEditablePosition.cs" />
|
<Compile Include="Rulesets\Edit\Types\IHasEditablePosition.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user