diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs index 1308b5ae3a..ec5d09d530 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; using osu.Framework.Input.Events; using osu.Game.Graphics; @@ -27,6 +28,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks private readonly Path path; private readonly List segments = new List(); + private readonly Container controlPointContainer; private Vector2 cursor; private PlacementState state; @@ -41,6 +43,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks path = new SmoothPath { PathWidth = 3 }, headMask = new CirclePlacementMask(), tailMask = new CirclePlacementMask(), + controlPointContainer = new Container { RelativeSizeAxes = Axes.Both } }; segments.Add(new Segment(Vector2.Zero)); @@ -64,6 +67,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks case PlacementState.Body: tailMask.Position = e.MousePosition; cursor = tailMask.Position - headMask.Position; + controlPointContainer.Last().NextPoint = e.MousePosition; return true; } @@ -88,6 +92,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks break; } + controlPointContainer.Add(new SliderControlPoint { Position = e.MousePosition }); + return true; } @@ -101,6 +107,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks protected override bool OnDoubleClick(DoubleClickEvent e) { segments.Add(new Segment(segments[segments.Count - 1].ControlPoints.Last())); + controlPointContainer.Last().SegmentSeparator = true; return true; } @@ -168,7 +175,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks public float Distance { get; private set; } public readonly List ControlPoints = new List(); - public IApproximator Approximator = new LinearApproximator(); public Segment(Vector2 offset) { @@ -183,17 +189,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks IApproximator approximator; - switch (Approximator) + switch (allControlPoints.Count) { - case null: + case 1: + case 2: approximator = new LinearApproximator(); break; - case LinearApproximator _ when allControlPoints.Count > 2: - case CircularArcApproximator _ when allControlPoints.Count > 3: - approximator = new BezierApproximator(); - break; default: - approximator = Approximator; + approximator = new BezierApproximator(); break; } diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs new file mode 100644 index 0000000000..d4aba5c1f5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs @@ -0,0 +1,95 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Caching; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Lines; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Edit.Masks +{ + public partial class SliderPlacementMask + { + /// + /// Todo: Move this out of SliderPlacementMask... + /// + private class SliderControlPoint : CompositeDrawable + { + private readonly Path path; + private readonly CircularContainer marker; + + private OsuColour colours; + + public SliderControlPoint() + { + Size = new Vector2(5); + Origin = Anchor.Centre; + + NextPoint = Position; + + 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 } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + this.colours = colours; + + marker.Colour = colours.YellowDark; + } + + public bool SegmentSeparator { set => marker.Colour = value ? colours.Red : colours.YellowDark; } + + private Vector2 nextPoint; + + public Vector2 NextPoint + { + set + { + nextPoint = value; + pathCache.Invalidate(); + } + } + + protected override void Update() + { + base.Update(); + + validatePath(); + } + + private Cached pathCache = new Cached(); + + private void validatePath() + { + if (pathCache.IsValid) + return; + + path.ClearVertices(); + path.AddVertex(nextPoint - Position); + path.AddVertex(Vector2.Zero); + path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero); + + pathCache.Validate(); + } + } + } +}