mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:43:05 +08:00
Use single path to display slider control point connections
This commit is contained in:
parent
002efca422
commit
cf313cd67f
@ -30,23 +30,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
});
|
});
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestAddOverlappingControlPoints()
|
|
||||||
{
|
|
||||||
createVisualiser(true);
|
|
||||||
|
|
||||||
addControlPointStep(new Vector2(200));
|
|
||||||
addControlPointStep(new Vector2(300));
|
|
||||||
addControlPointStep(new Vector2(300));
|
|
||||||
addControlPointStep(new Vector2(500, 300));
|
|
||||||
|
|
||||||
AddAssert("last connection displayed", () =>
|
|
||||||
{
|
|
||||||
var lastConnection = visualiser.Connections.Last(c => c.ControlPoint.Position == new Vector2(300));
|
|
||||||
return lastConnection.DrawWidth > 50;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPerfectCurveTooManyPoints()
|
public void TestPerfectCurveTooManyPoints()
|
||||||
{
|
{
|
||||||
@ -194,24 +177,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
addAssertPointPositionChanged(points, i);
|
addAssertPointPositionChanged(points, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestStackingUpdatesConnectionPosition()
|
|
||||||
{
|
|
||||||
createVisualiser(true);
|
|
||||||
|
|
||||||
Vector2 connectionPosition;
|
|
||||||
addControlPointStep(connectionPosition = new Vector2(300));
|
|
||||||
addControlPointStep(new Vector2(600));
|
|
||||||
|
|
||||||
// Apply a big number in stacking so the person running the test can clearly see if it fails
|
|
||||||
AddStep("apply stacking", () => slider.StackHeightBindable.Value += 10);
|
|
||||||
|
|
||||||
AddAssert($"Connection at {connectionPosition} changed",
|
|
||||||
() => visualiser.Connections[0].Position,
|
|
||||||
() => !Is.EqualTo(connectionPosition)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addAssertPointPositionChanged(Vector2[] points, int index)
|
private void addAssertPointPositionChanged(Vector2[] points, int index)
|
||||||
{
|
{
|
||||||
AddAssert($"Point at {points.ElementAt(index)} changed",
|
AddAssert($"Point at {points.ElementAt(index)} changed",
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Lines;
|
using osu.Framework.Graphics.Lines;
|
||||||
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 osuTK;
|
using osuTK;
|
||||||
@ -15,36 +12,21 @@ using osuTK;
|
|||||||
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A visualisation of the line between two <see cref="PathControlPointPiece{T}"/>s.
|
/// A visualisation of the lines between <see cref="PathControlPointPiece{T}"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of <see cref="OsuHitObject"/> which this <see cref="PathControlPointConnectionPiece{T}"/> visualises.</typeparam>
|
/// <typeparam name="T">The type of <see cref="OsuHitObject"/> which this <see cref="PathControlPointConnection{T}"/> visualises.</typeparam>
|
||||||
public partial class PathControlPointConnectionPiece<T> : CompositeDrawable where T : OsuHitObject, IHasPath
|
public partial class PathControlPointConnection<T> : SmoothPath where T : OsuHitObject, IHasPath
|
||||||
{
|
{
|
||||||
public readonly PathControlPoint ControlPoint;
|
|
||||||
|
|
||||||
private readonly Path path;
|
|
||||||
private readonly T hitObject;
|
private readonly T hitObject;
|
||||||
public int ControlPointIndex { get; set; }
|
|
||||||
|
|
||||||
private IBindable<Vector2> hitObjectPosition;
|
private IBindable<Vector2> hitObjectPosition;
|
||||||
private IBindable<int> pathVersion;
|
private IBindable<int> pathVersion;
|
||||||
private IBindable<int> stackHeight;
|
private IBindable<int> stackHeight;
|
||||||
|
|
||||||
public PathControlPointConnectionPiece(T hitObject, int controlPointIndex)
|
public PathControlPointConnection(T hitObject)
|
||||||
{
|
{
|
||||||
this.hitObject = hitObject;
|
this.hitObject = hitObject;
|
||||||
ControlPointIndex = controlPointIndex;
|
PathRadius = 1;
|
||||||
|
|
||||||
Origin = Anchor.Centre;
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
|
|
||||||
ControlPoint = hitObject.Path.ControlPoints[controlPointIndex];
|
|
||||||
|
|
||||||
InternalChild = path = new SmoothPath
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
PathRadius = 1
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -68,18 +50,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void updateConnectingPath()
|
private void updateConnectingPath()
|
||||||
{
|
{
|
||||||
Position = hitObject.StackedPosition + ControlPoint.Position;
|
Position = hitObject.StackedPosition;
|
||||||
|
|
||||||
path.ClearVertices();
|
ClearVertices();
|
||||||
|
|
||||||
int nextIndex = ControlPointIndex + 1;
|
foreach (var controlPoint in hitObject.Path.ControlPoints)
|
||||||
if (nextIndex == 0 || nextIndex >= hitObject.Path.ControlPoints.Count)
|
AddVertex(controlPoint.Position);
|
||||||
return;
|
|
||||||
|
|
||||||
path.AddVertex(Vector2.Zero);
|
OriginPosition = PositionInBoundingBox(Vector2.Zero);
|
||||||
path.AddVertex(hitObject.Path.ControlPoints[nextIndex].Position - ControlPoint.Position);
|
|
||||||
|
|
||||||
path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,7 +37,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // allow context menu to appear outside of the playfield.
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // allow context menu to appear outside of the playfield.
|
||||||
|
|
||||||
internal readonly Container<PathControlPointPiece<T>> Pieces;
|
internal readonly Container<PathControlPointPiece<T>> Pieces;
|
||||||
internal readonly Container<PathControlPointConnectionPiece<T>> Connections;
|
|
||||||
|
|
||||||
private readonly IBindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>();
|
private readonly IBindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>();
|
||||||
private readonly T hitObject;
|
private readonly T hitObject;
|
||||||
@ -63,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
Connections = new Container<PathControlPointConnectionPiece<T>> { RelativeSizeAxes = Axes.Both },
|
new PathControlPointConnection<T>(hitObject),
|
||||||
Pieces = new Container<PathControlPointPiece<T>> { RelativeSizeAxes = Axes.Both }
|
Pieces = new Container<PathControlPointPiece<T>> { RelativeSizeAxes = Axes.Both }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -185,17 +184,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
case NotifyCollectionChangedAction.Add:
|
case NotifyCollectionChangedAction.Add:
|
||||||
Debug.Assert(e.NewItems != null);
|
Debug.Assert(e.NewItems != null);
|
||||||
|
|
||||||
// If inserting in the path (not appending),
|
|
||||||
// update indices of existing connections after insert location
|
|
||||||
if (e.NewStartingIndex < Pieces.Count)
|
|
||||||
{
|
|
||||||
foreach (var connection in Connections)
|
|
||||||
{
|
|
||||||
if (connection.ControlPointIndex >= e.NewStartingIndex)
|
|
||||||
connection.ControlPointIndex += e.NewItems.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < e.NewItems.Count; i++)
|
for (int i = 0; i < e.NewItems.Count; i++)
|
||||||
{
|
{
|
||||||
var point = (PathControlPoint)e.NewItems[i];
|
var point = (PathControlPoint)e.NewItems[i];
|
||||||
@ -209,8 +197,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
d.DragInProgress = DragInProgress;
|
d.DragInProgress = DragInProgress;
|
||||||
d.DragEnded = DragEnded;
|
d.DragEnded = DragEnded;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Connections.Add(new PathControlPointConnectionPiece<T>(hitObject, e.NewStartingIndex + i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -222,19 +208,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
|||||||
{
|
{
|
||||||
foreach (var piece in Pieces.Where(p => p.ControlPoint == point).ToArray())
|
foreach (var piece in Pieces.Where(p => p.ControlPoint == point).ToArray())
|
||||||
piece.RemoveAndDisposeImmediately();
|
piece.RemoveAndDisposeImmediately();
|
||||||
foreach (var connection in Connections.Where(c => c.ControlPoint == point).ToArray())
|
|
||||||
connection.RemoveAndDisposeImmediately();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If removing before the end of the path,
|
|
||||||
// update indices of connections after remove location
|
|
||||||
if (e.OldStartingIndex < Pieces.Count)
|
|
||||||
{
|
|
||||||
foreach (var connection in Connections)
|
|
||||||
{
|
|
||||||
if (connection.ControlPointIndex >= e.OldStartingIndex)
|
|
||||||
connection.ControlPointIndex -= e.OldItems.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user