mirror of https://github.com/ppy/osu
Implement slider control point visualisation
This commit is contained in:
parent
9b19050faf
commit
b0f5ace0e8
|
@ -1,11 +1,14 @@
|
|||
// 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 osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks;
|
||||
using osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
@ -15,6 +18,16 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||
{
|
||||
public class TestCaseSliderSelectionMask : HitObjectSelectionMaskTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new Type[]
|
||||
{
|
||||
typeof(SliderSelectionMask),
|
||||
typeof(SliderCircleSelectionMask),
|
||||
typeof(SliderBodyPiece),
|
||||
typeof(SliderCircle),
|
||||
typeof(ControlPointVisualiser),
|
||||
typeof(ControlPointPiece)
|
||||
};
|
||||
|
||||
private readonly DrawableSlider drawableObject;
|
||||
|
||||
public TestCaseSliderSelectionMask()
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// 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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Lines;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components
|
||||
{
|
||||
public class ControlPointPiece : CompositeDrawable
|
||||
{
|
||||
private readonly Slider slider;
|
||||
private readonly int index;
|
||||
|
||||
private readonly Path path;
|
||||
private readonly CircularContainer marker;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
public ControlPointPiece(Slider slider, int index)
|
||||
{
|
||||
this.slider = slider;
|
||||
this.index = index;
|
||||
|
||||
Origin = Anchor.Centre;
|
||||
Size = new Vector2(10);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
path = new SmoothPath
|
||||
{
|
||||
BypassAutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
PathWidth = 1
|
||||
},
|
||||
marker = new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Position = slider.StackedPosition + slider.ControlPoints[index];
|
||||
|
||||
marker.Colour = segmentSeparator ? colours.Red : colours.Yellow;
|
||||
|
||||
path.ClearVertices();
|
||||
|
||||
if (index != slider.ControlPoints.Length - 1)
|
||||
{
|
||||
path.AddVertex(Vector2.Zero);
|
||||
path.AddVertex(slider.ControlPoints[index + 1] - slider.ControlPoints[index]);
|
||||
}
|
||||
|
||||
path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero);
|
||||
}
|
||||
|
||||
protected override bool OnDragStart(DragStartEvent e) => true;
|
||||
|
||||
protected override bool OnDrag(DragEvent e)
|
||||
{
|
||||
var newControlPoints = slider.ControlPoints.ToArray();
|
||||
newControlPoints[index] += e.Delta;
|
||||
|
||||
slider.ControlPoints = newControlPoints;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnDragEnd(DragEndEvent e) => true;
|
||||
|
||||
private bool segmentSeparator => index != 0 && index != slider.ControlPoints.Length - 1
|
||||
&& slider.ControlPoints[index - 1] != slider.ControlPoints[index]
|
||||
&& slider.ControlPoints[index + 1] != slider.ControlPoints[index];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components
|
||||
{
|
||||
public class ControlPointVisualiser : CompositeDrawable
|
||||
{
|
||||
private readonly Slider slider;
|
||||
|
||||
private readonly Container<ControlPointPiece> pieces;
|
||||
|
||||
public ControlPointVisualiser(Slider slider)
|
||||
{
|
||||
this.slider = slider;
|
||||
|
||||
InternalChild = pieces = new Container<ControlPointPiece> { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
slider.ControlPointsChanged += _ => updateControlPoints();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
private void updateControlPoints()
|
||||
{
|
||||
while (slider.ControlPoints.Length > pieces.Count)
|
||||
pieces.Add(new ControlPointPiece(slider, pieces.Count));
|
||||
while (slider.ControlPoints.Length < pieces.Count)
|
||||
pieces.Remove(pieces[pieces.Count - 1]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ public SliderSelectionMask(DrawableSlider slider)
|
|||
new SliderBodyPiece(sliderObject),
|
||||
headMask = new SliderCircleSelectionMask(slider.HeadCircle, sliderObject, SliderPosition.Start),
|
||||
new SliderCircleSelectionMask(slider.TailCircle, sliderObject, SliderPosition.End),
|
||||
new ControlPointVisualiser(sliderObject),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ public class Slider : OsuHitObject, IHasCurve
|
|||
/// </summary>
|
||||
private const float base_scoring_distance = 100;
|
||||
|
||||
public event Action<Vector2[]> ControlPointsChanged;
|
||||
|
||||
public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity;
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
|
@ -54,8 +56,15 @@ public override int IndexInCurrentCombo
|
|||
|
||||
public Vector2[] ControlPoints
|
||||
{
|
||||
get { return Curve.ControlPoints; }
|
||||
set { Curve.ControlPoints = value; }
|
||||
get => Curve.ControlPoints;
|
||||
set
|
||||
{
|
||||
if (Curve.ControlPoints == value)
|
||||
return;
|
||||
Curve.ControlPoints = value;
|
||||
|
||||
ControlPointsChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
public CurveType CurveType
|
||||
|
|
Loading…
Reference in New Issue