Separate path connections from control points

This commit is contained in:
smoogipoo 2019-12-10 11:20:08 +09:00
parent 1b14b0e5b6
commit e9ec6591a9
3 changed files with 92 additions and 45 deletions

View File

@ -0,0 +1,72 @@
// 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.
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Lines;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osuTK;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
{
public class PathControlPointConnection : CompositeDrawable
{
public PathControlPoint ControlPoint;
private readonly Path path;
private readonly Slider slider;
private IBindable<Vector2> sliderPosition;
private IBindable<int> pathVersion;
public PathControlPointConnection(Slider slider, PathControlPoint controlPoint)
{
this.slider = slider;
ControlPoint = controlPoint;
Origin = Anchor.Centre;
AutoSizeAxes = Axes.Both;
InternalChild = path = new SmoothPath
{
Anchor = Anchor.Centre,
PathRadius = 1
};
}
protected override void LoadComplete()
{
base.LoadComplete();
sliderPosition = slider.PositionBindable.GetBoundCopy();
sliderPosition.BindValueChanged(_ => updateConnectingPath());
pathVersion = slider.Path.Version.GetBoundCopy();
pathVersion.BindValueChanged(_ => updateConnectingPath());
updateConnectingPath();
}
/// <summary>
/// Updates the path connecting this control point to the next one.
/// </summary>
private void updateConnectingPath()
{
Position = slider.StackedPosition + ControlPoint.Position.Value;
path.ClearVertices();
int index = slider.Path.ControlPoints.IndexOf(ControlPoint) + 1;
if (index == 0 || index == slider.Path.ControlPoints.Count)
return;
path.AddVertex(Vector2.Zero);
path.AddVertex(slider.Path.ControlPoints[index].Position.Value - ControlPoint.Position.Value);
path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero);
}
}
}

View File

@ -6,7 +6,6 @@
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;
using osu.Framework.Graphics.Lines;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -28,7 +27,6 @@ public class PathControlPointPiece : BlueprintPiece<Slider>
public readonly PathControlPoint ControlPoint; public readonly PathControlPoint ControlPoint;
private readonly Slider slider; private readonly Slider slider;
private readonly Path path;
private readonly Container marker; private readonly Container marker;
private readonly Drawable markerRing; private readonly Drawable markerRing;
@ -39,12 +37,11 @@ public class PathControlPointPiece : BlueprintPiece<Slider>
private OsuColour colours { get; set; } private OsuColour colours { get; set; }
private IBindable<Vector2> sliderPosition; private IBindable<Vector2> sliderPosition;
private IBindable<int> pathVersion; private IBindable<Vector2> controlPointPosition;
public PathControlPointPiece(Slider slider, PathControlPoint controlPoint) public PathControlPointPiece(Slider slider, PathControlPoint controlPoint)
{ {
this.slider = slider; this.slider = slider;
ControlPoint = controlPoint; ControlPoint = controlPoint;
Origin = Anchor.Centre; Origin = Anchor.Centre;
@ -52,11 +49,6 @@ public PathControlPointPiece(Slider slider, PathControlPoint controlPoint)
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
path = new SmoothPath
{
Anchor = Anchor.Centre,
PathRadius = 1
},
marker = new Container marker = new Container
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
@ -96,20 +88,14 @@ protected override void LoadComplete()
base.LoadComplete(); base.LoadComplete();
sliderPosition = slider.PositionBindable.GetBoundCopy(); sliderPosition = slider.PositionBindable.GetBoundCopy();
sliderPosition.BindValueChanged(_ => updateDisplay()); sliderPosition.BindValueChanged(_ => updateMarkerDisplay());
pathVersion = slider.Path.Version.GetBoundCopy(); controlPointPosition = ControlPoint.Position.GetBoundCopy();
pathVersion.BindValueChanged(_ => updateDisplay()); controlPointPosition.BindValueChanged(_ => updateMarkerDisplay());
IsSelected.BindValueChanged(_ => updateMarkerDisplay()); IsSelected.BindValueChanged(_ => updateMarkerDisplay());
updateDisplay();
}
private void updateDisplay()
{
updateMarkerDisplay(); updateMarkerDisplay();
updateConnectingPath();
} }
// The connecting path is excluded from positional input // The connecting path is excluded from positional input
@ -189,26 +175,5 @@ private void updateMarkerDisplay()
colour = Color4.White; colour = Color4.White;
marker.Colour = colour; marker.Colour = colour;
} }
/// <summary>
/// Updates the path connecting this control point to the previous one.
/// </summary>
private void updateConnectingPath()
{
path.ClearVertices();
int index = slider.Path.ControlPoints.IndexOf(ControlPoint);
if (index == -1)
return;
if (++index != slider.Path.ControlPoints.Count)
{
path.AddVertex(Vector2.Zero);
path.AddVertex(slider.Path.ControlPoints[index].Position.Value - ControlPoint.Position.Value);
}
path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero);
}
} }
} }

View File

@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
public class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler<PlatformAction>, IHasContextMenu public class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler<PlatformAction>, IHasContextMenu
{ {
internal readonly Container<PathControlPointPiece> Pieces; internal readonly Container<PathControlPointPiece> Pieces;
private readonly Container<PathControlPointConnection> connections;
private readonly Slider slider; private readonly Slider slider;
private readonly bool allowSelection; private readonly bool allowSelection;
@ -42,7 +44,11 @@ public PathControlPointVisualiser(Slider slider, bool allowSelection)
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
InternalChild = Pieces = new Container<PathControlPointPiece> { RelativeSizeAxes = Axes.Both }; InternalChildren = new Drawable[]
{
connections = new Container<PathControlPointConnection> { RelativeSizeAxes = Axes.Both },
Pieces = new Container<PathControlPointPiece> { RelativeSizeAxes = Axes.Both }
};
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -62,19 +68,23 @@ private void addControlPoints(IEnumerable<PathControlPoint> controlPoints)
{ {
foreach (var point in controlPoints) foreach (var point in controlPoints)
{ {
var piece = new PathControlPointPiece(slider, point); Pieces.Add(new PathControlPointPiece(slider, point).With(d =>
{
if (allowSelection)
d.RequestSelection = selectPiece;
}));
if (allowSelection) connections.Add(new PathControlPointConnection(slider, point));
piece.RequestSelection = selectPiece;
Pieces.Add(piece);
} }
} }
private void removeControlPoints(IEnumerable<PathControlPoint> controlPoints) private void removeControlPoints(IEnumerable<PathControlPoint> controlPoints)
{ {
foreach (var point in controlPoints) foreach (var point in controlPoints)
{
Pieces.RemoveAll(p => p.ControlPoint == point); Pieces.RemoveAll(p => p.ControlPoint == point);
connections.RemoveAll(c => c.ControlPoint == point);
}
} }
protected override bool OnClick(ClickEvent e) protected override bool OnClick(ClickEvent e)