mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 16:06:06 +08:00
Move control point removal to SliderSelectionBlueprint
This commit is contained in:
parent
9831e3ad6b
commit
23959f3a3c
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -18,8 +17,6 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit.Compose;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||||
@ -34,11 +31,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
|
||||||
private IPlacementHandler placementHandler { get; set; }
|
|
||||||
|
|
||||||
private IBindableList<PathControlPoint> controlPoints;
|
private IBindableList<PathControlPoint> controlPoints;
|
||||||
|
|
||||||
|
public Action<List<PathControlPoint>> RemoveControlPointsRequested;
|
||||||
|
|
||||||
public PathControlPointVisualiser(Slider slider, bool allowSelection)
|
public PathControlPointVisualiser(Slider slider, bool allowSelection)
|
||||||
{
|
{
|
||||||
this.slider = slider;
|
this.slider = slider;
|
||||||
@ -123,29 +119,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
if (toRemove.Count == 0)
|
if (toRemove.Count == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var c in toRemove)
|
RemoveControlPointsRequested?.Invoke(toRemove);
|
||||||
{
|
|
||||||
// The first control point in the slider must have a type, so take it from the previous "first" one
|
|
||||||
// Todo: Should be handled within SliderPath itself
|
|
||||||
if (c == slider.Path.ControlPoints[0] && slider.Path.ControlPoints.Count > 1 && slider.Path.ControlPoints[1].Type.Value == null)
|
|
||||||
slider.Path.ControlPoints[1].Type.Value = slider.Path.ControlPoints[0].Type.Value;
|
|
||||||
|
|
||||||
slider.Path.ControlPoints.Remove(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
|
|
||||||
if (slider.Path.ControlPoints.Count <= 1)
|
|
||||||
{
|
|
||||||
placementHandler?.Delete(slider);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The path will have a non-zero offset if the head is removed, but sliders don't support this behaviour since the head is positioned at the slider's position
|
|
||||||
// So the slider needs to be offset by this amount instead, and all control points offset backwards such that the path is re-positioned at (0, 0)
|
|
||||||
Vector2 first = slider.Path.ControlPoints[0].Position.Value;
|
|
||||||
foreach (var c in slider.Path.ControlPoints)
|
|
||||||
c.Position.Value -= first;
|
|
||||||
slider.Position += first;
|
|
||||||
|
|
||||||
// Since pieces are re-used, they will not point to the deleted control points while remaining selected
|
// Since pieces are re-used, they will not point to the deleted control points while remaining selected
|
||||||
foreach (var piece in Pieces)
|
foreach (var piece in Pieces)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -14,6 +15,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
|
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using osu.Game.Screens.Edit.Compose;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
@ -29,6 +31,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private HitObjectComposer composer { get; set; }
|
private HitObjectComposer composer { get; set; }
|
||||||
|
|
||||||
|
[Resolved(CanBeNull = true)]
|
||||||
|
private IPlacementHandler placementHandler { get; set; }
|
||||||
|
|
||||||
public SliderSelectionBlueprint(DrawableSlider slider)
|
public SliderSelectionBlueprint(DrawableSlider slider)
|
||||||
: base(slider)
|
: base(slider)
|
||||||
{
|
{
|
||||||
@ -40,6 +45,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start),
|
HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start),
|
||||||
TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End),
|
TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End),
|
||||||
ControlPointVisualiser = new PathControlPointVisualiser(sliderObject, true)
|
ControlPointVisualiser = new PathControlPointVisualiser(sliderObject, true)
|
||||||
|
{
|
||||||
|
RemoveControlPointsRequested = removeControlPoints
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +105,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BindableList<PathControlPoint> controlPoints => HitObject.Path.ControlPoints;
|
||||||
|
|
||||||
private int addControlPoint(Vector2 position)
|
private int addControlPoint(Vector2 position)
|
||||||
{
|
{
|
||||||
position -= HitObject.Position;
|
position -= HitObject.Position;
|
||||||
@ -104,9 +114,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
int insertionIndex = 0;
|
int insertionIndex = 0;
|
||||||
float minDistance = float.MaxValue;
|
float minDistance = float.MaxValue;
|
||||||
|
|
||||||
for (int i = 0; i < HitObject.Path.ControlPoints.Count - 1; i++)
|
for (int i = 0; i < controlPoints.Count - 1; i++)
|
||||||
{
|
{
|
||||||
float dist = new Line(HitObject.Path.ControlPoints[i].Position.Value, HitObject.Path.ControlPoints[i + 1].Position.Value).DistanceToPoint(position);
|
float dist = new Line(controlPoints[i].Position.Value, controlPoints[i + 1].Position.Value).DistanceToPoint(position);
|
||||||
|
|
||||||
if (dist < minDistance)
|
if (dist < minDistance)
|
||||||
{
|
{
|
||||||
@ -116,11 +126,42 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move the control points from the insertion index onwards to make room for the insertion
|
// Move the control points from the insertion index onwards to make room for the insertion
|
||||||
HitObject.Path.ControlPoints.Insert(insertionIndex, new PathControlPoint { Position = { Value = position } });
|
controlPoints.Insert(insertionIndex, new PathControlPoint { Position = { Value = position } });
|
||||||
|
|
||||||
return insertionIndex;
|
return insertionIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeControlPoints(List<PathControlPoint> toRemove)
|
||||||
|
{
|
||||||
|
// Ensure that there are any points to be deleted
|
||||||
|
if (toRemove.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var c in toRemove)
|
||||||
|
{
|
||||||
|
// The first control point in the slider must have a type, so take it from the previous "first" one
|
||||||
|
// Todo: Should be handled within SliderPath itself
|
||||||
|
if (c == controlPoints[0] && controlPoints.Count > 1 && controlPoints[1].Type.Value == null)
|
||||||
|
controlPoints[1].Type.Value = controlPoints[0].Type.Value;
|
||||||
|
|
||||||
|
controlPoints.Remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
|
||||||
|
if (controlPoints.Count <= 1)
|
||||||
|
{
|
||||||
|
placementHandler?.Delete(HitObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path will have a non-zero offset if the head is removed, but sliders don't support this behaviour since the head is positioned at the slider's position
|
||||||
|
// So the slider needs to be offset by this amount instead, and all control points offset backwards such that the path is re-positioned at (0, 0)
|
||||||
|
Vector2 first = controlPoints[0].Position.Value;
|
||||||
|
foreach (var c in controlPoints)
|
||||||
|
c.Position.Value -= first;
|
||||||
|
HitObject.Position += first;
|
||||||
|
}
|
||||||
|
|
||||||
private void updatePath()
|
private void updatePath()
|
||||||
{
|
{
|
||||||
HitObject.Path.ExpectedDistance.Value = composer?.GetSnappedDistanceFromDistance(HitObject.StartTime, (float)HitObject.Path.CalculatedDistance) ?? (float)HitObject.Path.CalculatedDistance;
|
HitObject.Path.ExpectedDistance.Value = composer?.GetSnappedDistanceFromDistance(HitObject.StartTime, (float)HitObject.Path.CalculatedDistance) ?? (float)HitObject.Path.CalculatedDistance;
|
||||||
|
Loading…
Reference in New Issue
Block a user