diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSliderPlacementMask.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSliderPlacementMask.cs new file mode 100644 index 0000000000..ad75779d80 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSliderPlacementMask.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Edit.Masks.Slider; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Osu.Tests +{ + public class TestCaseSliderPlacementMask : HitObjectPlacementMaskTestCase + { + protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSlider((Slider)hitObject); + protected override PlacementMask CreateMask() => new SliderPlacementMask(); + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/Slider/Components/SliderControlPoint.cs b/osu.Game.Rulesets.Osu/Edit/Masks/Slider/Components/SliderControlPoint.cs new file mode 100644 index 0000000000..47bae20c30 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Masks/Slider/Components/SliderControlPoint.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.Slider.Components +{ + /// + /// Todo: Move this out of SliderPlacementMask... + /// + public 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(); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/Slider/SliderPlacementMask.cs similarity index 93% rename from osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs rename to osu.Game.Rulesets.Osu/Edit/Masks/Slider/SliderPlacementMask.cs index f663104acb..f23ab5b4dd 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/Slider/SliderPlacementMask.cs @@ -13,15 +13,15 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Edit.Masks.Slider.Components; using OpenTK; using OpenTK.Input; -namespace osu.Game.Rulesets.Osu.Edit.Masks +namespace osu.Game.Rulesets.Osu.Edit.Masks.Slider { - public partial class SliderPlacementMask : PlacementMask + public class SliderPlacementMask : PlacementMask { - public new Slider HitObject => (Slider)base.HitObject; + public new Objects.Slider HitObject => (Objects.Slider)base.HitObject; private Path path; private Container controlPointContainer; @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks private PlacementState state; public SliderPlacementMask() - : base(new Slider()) + : base(new Objects.Slider()) { RelativeSizeAxes = Axes.Both; segments.Add(new Segment(Vector2.Zero)); @@ -44,8 +44,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks InternalChildren = new Drawable[] { path = new SmoothPath { PathWidth = 3 }, - new CirclePlacementMask(HitObject.HeadCircle), - new CirclePlacementMask(HitObject.TailCircle), + new SliderCirclePiece(HitObject, SliderPosition.Start), + new SliderCirclePiece(HitObject, SliderPosition.End), controlPointContainer = new Container { RelativeSizeAxes = Axes.Both } }; diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderMasks/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderMasks/Components/SliderBodyPiece.cs index 3123a4fcea..141459a0d8 100644 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderMasks/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Masks/SliderMasks/Components/SliderBodyPiece.cs @@ -1,11 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components @@ -13,12 +15,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components public class SliderBodyPiece : CompositeDrawable { private readonly Slider slider; - private readonly SnakingSliderBody body; + private readonly ManualSliderBody body; public SliderBodyPiece(Slider slider) { this.slider = slider; - InternalChild = body = new SnakingSliderBody(slider) + + InternalChild = body = new ManualSliderBody { AccentColour = Color4.Transparent, PathWidth = slider.Scale * 64 @@ -41,11 +44,15 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks.SliderMasks.Components { base.Update(); + slider.Curve.Calculate(); + + var vertices = new List(); + slider.Curve.GetPathToProgress(vertices, 0, 1); + + body.SetVertices(vertices); + Size = body.Size; OriginPosition = body.PathOffset; - - // Need to cause one update - body.UpdateProgress(0); } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_CirclePlacementMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_CirclePlacementMask.cs deleted file mode 100644 index 390ea50e0d..0000000000 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_CirclePlacementMask.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; -using osu.Framework.Input.Events; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu.Objects; - -namespace osu.Game.Rulesets.Osu.Edit.Masks -{ - public partial class SliderPlacementMask - { - private class CirclePlacementMask : PlacementMask - { - public CirclePlacementMask(HitCircle hitCircle) - : base(hitCircle) - { - Origin = Anchor.Centre; - AutoSizeAxes = Axes.Both; - - InternalChild = new HitCircleMask(hitCircle); - - hitCircle.PositionChanged += _ => Position = hitCircle.StackedPosition; - } - - protected override bool Handle(UIEvent e) => false; - } - } -} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs deleted file mode 100644 index d4aba5c1f5..0000000000 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderPlacementMask_ControlPoint.cs +++ /dev/null @@ -1,95 +0,0 @@ -// 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(); - } - } - } -} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs deleted file mode 100644 index 46c807f4b3..0000000000 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask.cs +++ /dev/null @@ -1,67 +0,0 @@ -// 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.Graphics; -using osu.Framework.Graphics.Primitives; -using osu.Game.Graphics; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using OpenTK; -using OpenTK.Graphics; - -namespace osu.Game.Rulesets.Osu.Edit.Masks -{ - public partial class SliderSelectionMask : SelectionMask - { - private readonly SliderBody body; - private readonly DrawableSlider slider; - - public SliderSelectionMask(DrawableSlider slider) - : base(slider) - { - this.slider = slider; - - Position = slider.Position; - - var sliderObject = (Slider)slider.HitObject; - - InternalChildren = new Drawable[] - { - body = new SliderBody(sliderObject) - { - AccentColour = Color4.Transparent, - PathWidth = sliderObject.Scale * 64 - }, - new CircleSelectionMask(slider.HeadCircle, slider), - new CircleSelectionMask(slider.TailCircle, slider), - }; - - sliderObject.PositionChanged += _ => Position = slider.Position; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - body.BorderColour = colours.Yellow; - } - - protected override void Update() - { - base.Update(); - - Size = slider.Size; - OriginPosition = slider.OriginPosition; - - // Need to cause one update - body.UpdateProgress(0); - } - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); - - public override Vector2 SelectionPoint => ToScreenSpace(OriginPosition); - public override Quad SelectionQuad => body.PathDrawQuad; - } -} diff --git a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask_CircleSelectionMask.cs b/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask_CircleSelectionMask.cs deleted file mode 100644 index f4d4749343..0000000000 --- a/osu.Game.Rulesets.Osu/Edit/Masks/SliderSelectionMask_CircleSelectionMask.cs +++ /dev/null @@ -1,64 +0,0 @@ -// 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.Graphics; -using osu.Game.Graphics; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; -using OpenTK; - -namespace osu.Game.Rulesets.Osu.Edit.Masks -{ - public partial class SliderSelectionMask - { - private class CircleSelectionMask : SelectionMask - { - public CircleSelectionMask(DrawableHitCircle sliderHead, DrawableSlider slider) - : this(sliderHead, Vector2.Zero, slider) - { - } - - public CircleSelectionMask(DrawableSliderTail sliderTail, DrawableSlider slider) - : this(sliderTail, ((Slider)slider.HitObject).Curve.PositionAt(1), slider) - { - } - - private readonly DrawableOsuHitObject hitObject; - - private CircleSelectionMask(DrawableOsuHitObject hitObject, Vector2 position, DrawableSlider slider) - : base(hitObject) - { - this.hitObject = hitObject; - - Origin = Anchor.Centre; - - Position = position; - Size = slider.HeadCircle.Size; - Scale = slider.HeadCircle.Scale; - - AddInternal(new RingPiece()); - - Select(); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Colour = colours.Yellow; - } - - protected override void Update() - { - base.Update(); - - RelativeAnchorPosition = hitObject.RelativeAnchorPosition; - } - - // Todo: This is temporary, since the slider circle masks don't do anything special yet. In the future they will handle input. - public override bool HandlePositionalInput => false; - } - } -} diff --git a/osu.Game.Rulesets.Osu/Edit/SliderCompositionTool.cs b/osu.Game.Rulesets.Osu/Edit/SliderCompositionTool.cs index f7cdd76655..30ebc51179 100644 --- a/osu.Game.Rulesets.Osu/Edit/SliderCompositionTool.cs +++ b/osu.Game.Rulesets.Osu/Edit/SliderCompositionTool.cs @@ -3,7 +3,7 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; -using osu.Game.Rulesets.Osu.Edit.Masks; +using osu.Game.Rulesets.Osu.Edit.Masks.Slider; using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Edit diff --git a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs index 196cb9320a..61647ffdc5 100644 --- a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs @@ -37,8 +37,6 @@ namespace osu.Game.Tests.Visual typeof(HitCirclePiece), typeof(HitCircleSelectionMask), typeof(HitCirclePlacementMask), - typeof(SliderSelectionMask), - typeof(SliderPlacementMask) }; private HitObjectComposer composer;