1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 05:32:54 +08:00

Bring up to date with further placement changes

This commit is contained in:
smoogipoo 2018-10-25 19:34:35 +09:00
parent 8b36d9b482
commit b28f44087d
10 changed files with 134 additions and 270 deletions

View File

@ -0,0 +1,19 @@
// 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.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();
}
}

View File

@ -0,0 +1,95 @@
// 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.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
{
/// <summary>
/// Todo: Move this out of SliderPlacementMask...
/// </summary>
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();
}
}
}

View File

@ -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<SliderControlPoint> 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<SliderControlPoint> { RelativeSizeAxes = Axes.Both }
};

View File

@ -1,11 +1,13 @@
// 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.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<Vector2>();
slider.Curve.GetPathToProgress(vertices, 0, 1);
body.SetVertices(vertices);
Size = body.Size;
OriginPosition = body.PathOffset;
// Need to cause one update
body.UpdateProgress(0);
}
}
}

View File

@ -1,29 +0,0 @@
// 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.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;
}
}
}

View File

@ -1,95 +0,0 @@
// 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.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
{
/// <summary>
/// Todo: Move this out of SliderPlacementMask...
/// </summary>
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();
}
}
}
}

View File

@ -1,67 +0,0 @@
// 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.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;
}
}

View File

@ -1,64 +0,0 @@
// 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.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;
}
}
}

View File

@ -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

View File

@ -37,8 +37,6 @@ namespace osu.Game.Tests.Visual
typeof(HitCirclePiece),
typeof(HitCircleSelectionMask),
typeof(HitCirclePlacementMask),
typeof(SliderSelectionMask),
typeof(SliderPlacementMask)
};
private HitObjectComposer composer;