Add basic slider distance control

This commit is contained in:
OliBomby 2023-12-20 00:05:32 +01:00
parent 1ebb6262fd
commit 22a0bc7d9d
5 changed files with 112 additions and 8 deletions

View File

@ -353,7 +353,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public new SliderBodyPiece BodyPiece => base.BodyPiece;
public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay;
public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay;
public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailPiece;
public new PathControlPointVisualiser<Slider> ControlPointVisualiser => base.ControlPointVisualiser;
public TestSliderBlueprint(Slider slider)

View File

@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public new SliderBodyPiece BodyPiece => base.BodyPiece;
public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay;
public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay;
public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailPiece;
public new PathControlPointVisualiser<Slider> ControlPointVisualiser => base.ControlPointVisualiser;
public TestSliderBlueprint(Slider slider)

View File

@ -0,0 +1,104 @@
// 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.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
{
public partial class SliderTailPiece : SliderCircleOverlay
{
/// <summary>
/// Whether this is currently being dragged.
/// </summary>
private bool isDragging;
private InputManager inputManager = null!;
[Resolved(CanBeNull = true)]
private EditorBeatmap? editorBeatmap { get; set; }
[Resolved]
private OsuColour colours { get; set; } = null!;
public SliderTailPiece(Slider slider, SliderPosition position)
: base(slider, position)
{
}
protected override void LoadComplete()
{
base.LoadComplete();
inputManager = GetContainingInputManager();
}
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => CirclePiece.ReceivePositionalInputAt(screenSpacePos);
protected override bool OnHover(HoverEvent e)
{
updateCirclePieceColour();
return false;
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateCirclePieceColour();
}
private void updateCirclePieceColour()
{
Color4 colour = colours.Yellow;
if (IsHovered)
colour = colour.Lighten(1);
CirclePiece.Colour = colour;
}
protected override bool OnDragStart(DragStartEvent e)
{
if (e.Button == MouseButton.Right || !inputManager.CurrentState.Keyboard.ShiftPressed)
return false;
isDragging = true;
editorBeatmap?.BeginChange();
return true;
}
protected override void OnDrag(DragEvent e)
{
double proposedDistance = Slider.Path.Distance + e.Delta.X;
proposedDistance = MathHelper.Clamp(proposedDistance, 0, Slider.Path.CalculatedDistance);
proposedDistance = MathHelper.Clamp(proposedDistance,
0.1 * Slider.Path.Distance / Slider.SliderVelocityMultiplier,
10 * Slider.Path.Distance / Slider.SliderVelocityMultiplier);
if (Precision.AlmostEquals(proposedDistance, Slider.Path.Distance))
return;
Slider.SliderVelocityMultiplier *= proposedDistance / Slider.Path.Distance;
Slider.Path.ExpectedDistance.Value = proposedDistance;
editorBeatmap?.Update(Slider);
}
protected override void OnDragEnd(DragEndEvent e)
{
if (isDragging)
{
editorBeatmap?.EndChange();
}
}
}
}

View File

@ -11,14 +11,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
public partial class SliderCircleOverlay : CompositeDrawable
{
protected readonly HitCirclePiece CirclePiece;
protected readonly Slider Slider;
private readonly Slider slider;
private readonly SliderPosition position;
private readonly HitCircleOverlapMarker marker;
private readonly SliderPosition position;
public SliderCircleOverlay(Slider slider, SliderPosition position)
{
this.slider = slider;
Slider = slider;
this.position = position;
InternalChildren = new Drawable[]
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
{
base.Update();
var circle = position == SliderPosition.Start ? (HitCircle)slider.HeadCircle : slider.TailCircle;
var circle = position == SliderPosition.Start ? (HitCircle)Slider.HeadCircle : Slider.TailCircle;
CirclePiece.UpdateFrom(circle);
marker.UpdateFrom(circle);

View File

@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
protected SliderBodyPiece BodyPiece { get; private set; }
protected SliderCircleOverlay HeadOverlay { get; private set; }
protected SliderCircleOverlay TailOverlay { get; private set; }
protected SliderTailPiece TailPiece { get; private set; }
[CanBeNull]
protected PathControlPointVisualiser<Slider> ControlPointVisualiser { get; private set; }
@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
{
BodyPiece = new SliderBodyPiece(),
HeadOverlay = CreateCircleOverlay(HitObject, SliderPosition.Start),
TailOverlay = CreateCircleOverlay(HitObject, SliderPosition.End),
TailPiece = new SliderTailPiece(HitObject, SliderPosition.End),
};
}