diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index 7b665b1ff9..278c7b1bde 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor { public partial class TestSceneJuiceStreamSelectionBlueprint : CatchSelectionBlueprintTestScene { - private JuiceStream hitObject; + private JuiceStream hitObject = null!; private readonly ManualClock manualClock = new ManualClock(); @@ -193,6 +191,17 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor addVertexCheckStep(1, 0, times[0], positions[0]); } + [Test] + public void TestDeletingSecondVertexDeletesEntireJuiceStream() + { + double[] times = { 100, 400 }; + float[] positions = { 100, 150 }; + addBlueprintStep(times, positions); + + addDeleteVertexSteps(times[1], positions[1]); + AddAssert("juice stream deleted", () => EditorBeatmap.HitObjects, () => Is.Empty); + } + [Test] public void TestVertexResampling() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index e626392234..6a671458f0 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components })); } - public void UpdateHitObjectFromPath(JuiceStream hitObject) + public virtual void UpdateHitObjectFromPath(JuiceStream hitObject) { // The SV setting may need to be changed for the current path. var svBindable = hitObject.SliderVelocityMultiplierBindable; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index b2ee43ba16..26b26641d3 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -138,5 +138,13 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components EditorBeatmap?.EndChange(); } + + public override void UpdateHitObjectFromPath(JuiceStream hitObject) + { + base.UpdateHitObjectFromPath(hitObject); + + if (hitObject.Path.ControlPoints.Count <= 1 || !hitObject.Path.HasValidLength) + EditorBeatmap?.Remove(hitObject); + } } } diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index 67d4429be8..cddde34aca 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Edit.Timing [Cached] public readonly Bindable SelectedGroup = new Bindable(); + private readonly Bindable currentEditorMode = new Bindable(); + [Resolved] private EditorClock? editorClock { get; set; } @@ -41,18 +43,35 @@ namespace osu.Game.Screens.Edit.Timing } }; + [BackgroundDependencyLoader] + private void load(Editor? editor) + { + if (editor != null) + currentEditorMode.BindTo(editor.Mode); + } + protected override void LoadComplete() { base.LoadComplete(); - if (editorClock != null) + // When entering the timing screen, let's choose the closest valid timing point. + // This will emulate the osu-stable behaviour where a metronome and timing information + // are presented on entering the screen. + currentEditorMode.BindValueChanged(mode => { - // When entering the timing screen, let's choose the closest valid timing point. - // This will emulate the osu-stable behaviour where a metronome and timing information - // are presented on entering the screen. - var nearestTimingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(editorClock.CurrentTime); - SelectedGroup.Value = EditorBeatmap.ControlPointInfo.GroupAt(nearestTimingPoint.Time); - } + if (mode.NewValue == EditorScreenMode.Timing) + selectClosestTimingPoint(); + }); + selectClosestTimingPoint(); + } + + private void selectClosestTimingPoint() + { + if (editorClock == null) + return; + + var nearestTimingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(editorClock.CurrentTime); + SelectedGroup.Value = EditorBeatmap.ControlPointInfo.GroupAt(nearestTimingPoint.Time); } protected override void ConfigureTimeline(TimelineArea timelineArea)