From 19ee05c232eb86710001bdad3bef2e135f7bc97a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 17 Jan 2022 20:09:02 +0300 Subject: [PATCH 01/27] Add "distance spacing" multiplier for osu! ruleset While osu!catch also implements a distance snap grid, it doesn't rely on `GetBeatSnapDistanceAt` (unlike osu!), therefore it can't have the "distance spacing" multiplier yet. --- .../Edit/CatchHitObjectComposer.cs | 2 + .../Edit/ManiaHitObjectComposer.cs | 2 + .../Edit/OsuHitObjectComposer.cs | 2 + .../Edit/TaikoHitObjectComposer.cs | 2 + .../UserInterface/ExpandableSlider.cs | 9 ++ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 101 +++++++++++++++++- 6 files changed, 116 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 164f465438..19595de3b1 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.Edit private readonly Bindable distanceSnapToggle = new Bindable(); + protected override bool SupportsDistanceSpacing => false; + private InputManager inputManager; public CatchHitObjectComposer(CatchRuleset ruleset) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 2baec95c94..5752f9f014 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Mania.Edit private ManiaBeatSnapGrid beatSnapGrid; private InputManager inputManager; + protected override bool SupportsDistanceSpacing => false; + public ManiaHitObjectComposer(Ruleset ruleset) : base(ruleset) { diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 1e84ec80e1..e7eabdc748 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuHitObjectComposer : HitObjectComposer { + protected override bool SupportsDistanceSpacing => true; + public OsuHitObjectComposer(Ruleset ruleset) : base(ruleset) { diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 161799c980..af9bc6c3a3 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -11,6 +11,8 @@ namespace osu.Game.Rulesets.Taiko.Edit { public class TaikoHitObjectComposer : HitObjectComposer { + protected override bool SupportsDistanceSpacing => false; + public TaikoHitObjectComposer(TaikoRuleset ruleset) : base(ruleset) { diff --git a/osu.Game/Graphics/UserInterface/ExpandableSlider.cs b/osu.Game/Graphics/UserInterface/ExpandableSlider.cs index 60e83f9c81..a05c0cfab0 100644 --- a/osu.Game/Graphics/UserInterface/ExpandableSlider.cs +++ b/osu.Game/Graphics/UserInterface/ExpandableSlider.cs @@ -70,6 +70,15 @@ namespace osu.Game.Graphics.UserInterface set => slider.Current = value; } + /// + /// A custom step value for each key press which actuates a change on this control. + /// + public float KeyboardStep + { + get => slider.KeyboardStep; + set => slider.KeyboardStep = value; + } + public BindableBool Expanded { get; } = new BindableBool(); public override bool HandlePositionalInput => true; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 39783cc8bb..528ba2fb8b 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -14,6 +14,8 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings.Sections; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -56,6 +58,26 @@ namespace osu.Game.Rulesets.Edit [Resolved] protected IBeatSnapProvider BeatSnapProvider { get; private set; } + /// + /// Whether this composer supports a "distance spacing" multiplier for distance snap grids. + /// + /// + /// Setting this to displays a "distance spacing" slider and allows this composer to configure the value of . + /// + protected abstract bool SupportsDistanceSpacing { get; } + + private readonly BindableFloat distanceSpacing = new BindableFloat + { + Default = 1.0f, + MinValue = 0.1f, + MaxValue = 6.0f, + Precision = 0.01f, + }; + + public override IBindable DistanceSpacingMultiplier => distanceSpacing; + + private SnappingToolboxContainer snappingToolboxContainer; + protected ComposeBlueprintContainer BlueprintContainer { get; private set; } private DrawableEditorRulesetWrapper drawableRulesetWrapper; @@ -117,6 +139,8 @@ namespace osu.Game.Rulesets.Edit }, new LeftToolboxFlow { + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, Children = new Drawable[] { new EditorToolboxGroup("toolbox (1-9)") @@ -132,11 +156,41 @@ namespace osu.Game.Rulesets.Edit Direction = FillDirection.Vertical, Spacing = new Vector2(0, 5), }, - } + }, } }, }; + distanceSpacing.Value = (float)EditorBeatmap.BeatmapInfo.DistanceSpacing; + + if (SupportsDistanceSpacing) + { + ExpandableSlider distanceSpacingSlider; + + AddInternal(snappingToolboxContainer = new SnappingToolboxContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Child = new EditorToolboxGroup("snapping") + { + Child = distanceSpacingSlider = new ExpandableSlider + { + Current = { BindTarget = distanceSpacing }, + KeyboardStep = 0.01f, + } + } + }); + + distanceSpacing.BindValueChanged(v => + { + distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; + distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; + EditorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; + }, true); + } + else + distanceSpacing.Disabled = true; + toolboxCollection.Items = CompositionTools .Prepend(new SelectTool()) .Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon)) @@ -211,8 +265,17 @@ namespace osu.Game.Rulesets.Edit #region Tool selection logic + private bool distanceSpacingScrollActive; + protected override bool OnKeyDown(KeyDownEvent e) { + if (SupportsDistanceSpacing && e.AltPressed && e.Key == Key.D && !e.Repeat) + { + snappingToolboxContainer.Expanded.Value = true; + distanceSpacingScrollActive = true; + return true; + } + if (e.ControlPressed || e.AltPressed || e.SuperPressed) return false; @@ -242,6 +305,28 @@ namespace osu.Game.Rulesets.Edit return base.OnKeyDown(e); } + protected override void OnKeyUp(KeyUpEvent e) + { + if (distanceSpacingScrollActive && (e.Key == Key.AltLeft || e.Key == Key.AltRight || e.Key == Key.D)) + { + snappingToolboxContainer.Expanded.Value = false; + distanceSpacingScrollActive = false; + } + + base.OnKeyUp(e); + } + + protected override bool OnScroll(ScrollEvent e) + { + if (distanceSpacingScrollActive) + { + distanceSpacing.Value += e.ScrollDelta.Y * (e.ShiftPressed || e.IsPrecise ? 0.01f : 0.1f); + return true; + } + + return base.OnScroll(e); + } + private bool checkLeftToggleFromKey(Key key, out int index) { if (key < Key.Number1 || key > Key.Number9) @@ -383,7 +468,7 @@ namespace osu.Game.Rulesets.Edit public override float GetBeatSnapDistanceAt(HitObject referenceObject) { - return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * referenceObject.DifficultyControlPoint.SliderVelocity / BeatSnapProvider.BeatDivisor); + return (float)(100 * referenceObject.DifficultyControlPoint.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier * distanceSpacing.Value / BeatSnapProvider.BeatDivisor); } public override float DurationToDistance(HitObject referenceObject, double duration) @@ -432,6 +517,18 @@ namespace osu.Game.Rulesets.Edit FillFlow.Spacing = new Vector2(10); } } + + private class SnappingToolboxContainer : ExpandingContainer + { + public SnappingToolboxContainer() + : base(130, 250) + { + RelativeSizeAxes = Axes.Y; + Padding = new MarginPadding { Left = 10 }; + + FillFlow.Spacing = new Vector2(10); + } + } } /// From 528dc03b8c06b94d1b45c0d07e8b681ba109fe00 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 18 Jan 2022 15:25:32 +0300 Subject: [PATCH 02/27] Expose distance spacing in `IPositionSnapProvider` for updating distance grid Alternate method is to expose a `SnapDistancesChanged` event in `IPositionSnapProvider` instead, but I chose this way as an analogue to `IBeatSnapProvider.BeatDivisor`, which might even make sense to be exposed as `BindableBeatDivisor` instead of caching that separately. --- .../Editor/TestSceneManiaBeatSnapGrid.cs | 3 +++ .../Editor/TestSceneOsuDistanceSnapGrid.cs | 3 +++ .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 3 +++ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 ++ osu.Game/Rulesets/Edit/IPositionSnapProvider.cs | 8 ++++++++ .../Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 6 ++++++ .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 ++ 7 files changed, 27 insertions(+) diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index 50be13c4e0..38779ab47b 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Framework.Timing; @@ -98,6 +99,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor set => InternalChild = value; } + public override IBindable DistanceSpacingMultiplier => throw new System.NotImplementedException(); + public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) { throw new System.NotImplementedException(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index c770e2d96f..c5829d5351 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -4,6 +4,7 @@ using System; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -186,6 +187,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); + public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public float GetBeatSnapDistanceAt(HitObject referenceObject) => (float)beat_length; public float DurationToDistance(HitObject referenceObject, double duration) => (float)duration; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 0d9e06e471..cba6d7692d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; @@ -166,6 +167,8 @@ namespace osu.Game.Tests.Visual.Editing public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); + public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public float GetBeatSnapDistanceAt(HitObject referenceObject) => 10; public float DurationToDistance(HitObject referenceObject, double duration) => (float)duration; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 528ba2fb8b..6cdc2699aa 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -563,6 +563,8 @@ namespace osu.Game.Rulesets.Edit #region IPositionSnapProvider + public abstract IBindable DistanceSpacingMultiplier { get; } + public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition); public virtual SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) => diff --git a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs index 743a2f41fc..1cfcb86e10 100644 --- a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Bindables; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osuTK; @@ -8,6 +10,12 @@ namespace osu.Game.Rulesets.Edit { public interface IPositionSnapProvider { + /// + /// The spacing multiplier applied to beat snap distances. + /// + /// + IBindable DistanceSpacingMultiplier { get; } + /// /// Given a position, find a valid time and position snap. /// diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 05bf405f3c..afbe83ec83 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -52,6 +53,8 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private BindableBeatDivisor beatDivisor { get; set; } + private IBindable distanceSpacingMultiplier; + private readonly LayoutValue gridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); private readonly double? endTime; @@ -82,6 +85,9 @@ namespace osu.Game.Screens.Edit.Compose.Components base.LoadComplete(); beatDivisor.BindValueChanged(_ => updateSpacing(), true); + + distanceSpacingMultiplier = SnapProvider.DistanceSpacingMultiplier.GetBoundCopy(); + distanceSpacingMultiplier.BindValueChanged(_ => updateSpacing(), true); } private void updateSpacing() diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 51cca4ceff..f3a328c6bc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -317,6 +317,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private double getTimeFromPosition(Vector2 localPosition) => (localPosition.X / Content.DrawWidth) * track.Length; + public IBindable DistanceSpacingMultiplier => throw new NotImplementedException(); + public float GetBeatSnapDistanceAt(HitObject referenceObject) => throw new NotImplementedException(); public float DurationToDistance(HitObject referenceObject, double duration) => throw new NotImplementedException(); From 9504942cfda38af4e6c5c15450a8258f1082de8c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 18 Jan 2022 18:30:31 +0300 Subject: [PATCH 03/27] Add test case for distance spacing hotkeys scrolling behaviour --- .../Editing/TestSceneHitObjectComposer.cs | 24 +++++++++++++++++++ osu.Game/Overlays/SettingsToolboxGroup.cs | 7 ++++++ 2 files changed, 31 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 145d738f60..7ac511e761 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; @@ -21,6 +22,7 @@ using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.RadioButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { @@ -86,6 +88,28 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("Tool changed", () => hitObjectComposer.ChildrenOfType().First().CurrentTool is HitCircleCompositionTool); } + [Test] + public void TestDistanceSpacingHotkeys() + { + float originalSpacing = 0; + + AddStep("retrieve original spacing", () => originalSpacing = (float)editorBeatmap.BeatmapInfo.DistanceSpacing); + + AddStep("hold alt", () => InputManager.PressKey(Key.LAlt)); + AddStep("hold D", () => InputManager.PressKey(Key.D)); + + AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); + AddAssert("distance spacing increased by 0.5", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.5f)); + + AddStep("hold shift", () => InputManager.PressKey(Key.LShift)); + AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); + AddAssert("distance spacing increased by 0.05", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.55f)); + + AddStep("release shift", () => InputManager.ReleaseKey(Key.LShift)); + AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); + AddStep("release D", () => InputManager.ReleaseKey(Key.D)); + } + public class EditorBeatmapContainer : Container { private readonly IWorkingBeatmap working; diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 08321f68fe..509410ec20 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -22,6 +22,11 @@ namespace osu.Game.Overlays { public class SettingsToolboxGroup : Container, IExpandable { + /// + /// The title of this toolbox group. + /// + public string Title { get; } + private const float transition_duration = 250; private const int container_width = 270; private const int border_thickness = 2; @@ -48,6 +53,8 @@ namespace osu.Game.Overlays /// The title to be displayed in the header of this group. public SettingsToolboxGroup(string title) { + Title = title; + AutoSizeAxes = Axes.Y; Width = container_width; Masking = true; From 500322ff214753e17a78ca5bb601412ba27e7447 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 23 Jan 2022 06:13:56 +0300 Subject: [PATCH 04/27] Update failing snap test scenes --- .../Editor/TestSceneObjectObjectSnap.cs | 7 +++++++ .../Editor/TestSceneSliderSnapping.cs | 10 +++++++++- .../TestSceneHitObjectComposerDistanceSnapping.cs | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index 7bdf131e0d..41304dcd24 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -3,9 +3,11 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Bindables; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; @@ -26,6 +28,11 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor base.SetUpSteps(); AddStep("get playfield", () => playfield = Editor.ChildrenOfType().First()); AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time)); + AddStep("set distance spacing to 1", () => + { + var distanceSpacing = (BindableFloat)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + distanceSpacing.Value = 1; + }); } [TestCase(true)] diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index b43b2b1461..23131668a0 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -3,12 +3,15 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Input.Events; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; @@ -61,9 +64,14 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor })); AddStep("set beat divisor to 1/1", () => { - var beatDivisor = (BindableBeatDivisor)Editor.Dependencies.Get(typeof(BindableBeatDivisor)); + var beatDivisor = Editor.Dependencies.Get(); beatDivisor.Value = 1; }); + AddStep("set distance spacing to 1", () => + { + var distanceSpacing = (BindableFloat)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + distanceSpacing.Value = 1; + }); } [Test] diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 43f22e4e90..d9312cb7ae 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -61,6 +61,7 @@ namespace osu.Game.Tests.Editing BeatDivisor.Value = 1; composer.EditorBeatmap.Difficulty.SliderMultiplier = 1; + composer.EditorBeatmap.BeatmapInfo.DistanceSpacing = 1; composer.EditorBeatmap.ControlPointInfo.Clear(); composer.EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); }); From 868dcd20f56d208d41bdc769f4266b91fd355c84 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 26 Jan 2022 11:39:31 +0300 Subject: [PATCH 05/27] Remove `e.ShiftPressed` handling for now Broken on macOS, will be handled differently later on as discussed. --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 6cdc2699aa..948e1d770f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -320,7 +320,7 @@ namespace osu.Game.Rulesets.Edit { if (distanceSpacingScrollActive) { - distanceSpacing.Value += e.ScrollDelta.Y * (e.ShiftPressed || e.IsPrecise ? 0.01f : 0.1f); + distanceSpacing.Value += e.ScrollDelta.Y * (e.IsPrecise ? 0.01f : 0.1f); return true; } From cbc8f7ff90e95b0d0b1876ac8f0634ac5575f643 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 15 Feb 2022 02:29:09 +0300 Subject: [PATCH 06/27] Remove test coverage of "shift" hotkey behaviour --- osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 7ac511e761..d542732e19 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -101,11 +101,6 @@ namespace osu.Game.Tests.Visual.Editing AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); AddAssert("distance spacing increased by 0.5", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.5f)); - AddStep("hold shift", () => InputManager.PressKey(Key.LShift)); - AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); - AddAssert("distance spacing increased by 0.05", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.55f)); - - AddStep("release shift", () => InputManager.ReleaseKey(Key.LShift)); AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); AddStep("release D", () => InputManager.ReleaseKey(Key.D)); } From f7edf25d4c84e2bc61a3f95efd22de52409fc66b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 16 Feb 2022 03:23:02 +0300 Subject: [PATCH 07/27] Remove no longer required property --- osu.Game/Overlays/SettingsToolboxGroup.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 509410ec20..08321f68fe 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -22,11 +22,6 @@ namespace osu.Game.Overlays { public class SettingsToolboxGroup : Container, IExpandable { - /// - /// The title of this toolbox group. - /// - public string Title { get; } - private const float transition_duration = 250; private const int container_width = 270; private const int border_thickness = 2; @@ -53,8 +48,6 @@ namespace osu.Game.Overlays /// The title to be displayed in the header of this group. public SettingsToolboxGroup(string title) { - Title = title; - AutoSizeAxes = Axes.Y; Width = container_width; Masking = true; From 7654584e40e8860a20f6bfce1322d6b331da92af Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 16 Feb 2022 03:25:03 +0300 Subject: [PATCH 08/27] Allow using `SizeSlider` on different value types --- .../Visual/UserInterface/TestSceneExpandingContainer.cs | 4 ++-- .../Overlays/Settings/Sections/Gameplay/InputSettings.cs | 2 +- osu.Game/Overlays/Settings/Sections/SizeSlider.cs | 6 ++++-- .../Settings/Sections/UserInterface/GeneralSettings.cs | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs index f4920b4412..288c0cb140 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface private TestExpandingContainer container; private SettingsToolboxGroup toolboxGroup; - private ExpandableSlider slider1; + private ExpandableSlider> slider1; private ExpandableSlider slider2; [SetUp] @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.UserInterface Width = 1, Children = new Drawable[] { - slider1 = new ExpandableSlider + slider1 = new ExpandableSlider> { Current = new BindableFloat { diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs index 962572ca6e..83ea655601 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Children = new Drawable[] { - new SettingsSlider + new SettingsSlider> { LabelText = SkinSettingsStrings.GameplayCursorSize, Current = config.GetBindable(OsuSetting.GameplayCursorSize), diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index 8aeb440be1..cc2c77adf2 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; @@ -9,8 +10,9 @@ namespace osu.Game.Overlays.Settings.Sections /// /// A slider intended to show a "size" multiplier number, where 1x is 1.0. /// - internal class SizeSlider : OsuSliderBar + internal class SizeSlider : OsuSliderBar + where T : struct, IEquatable, IComparable, IConvertible, IFormattable { - public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x"); + public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", null); } } diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index 0afbed5df5..66702744d3 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface LabelText = UserInterfaceStrings.CursorRotation, Current = config.GetBindable(OsuSetting.CursorRotation) }, - new SettingsSlider + new SettingsSlider> { LabelText = UserInterfaceStrings.MenuCursorSize, Current = config.GetBindable(OsuSetting.MenuCursorSize), From 0992bec2c849d9e5a7be97d1d9396027a1f8f4e1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 16 Feb 2022 03:28:05 +0300 Subject: [PATCH 09/27] Change "distance spacing" multipler type to `double` Avoids losing precision on initial load, causing an unnecessary hash change in `EditorChangeHandler`. Resolves test failures in `TestSceneEditorChangeStates` (https://github.com/ppy/osu/runs/5192493482?check_suite_focus=true). --- .../Editor/TestSceneManiaBeatSnapGrid.cs | 2 +- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 2 +- .../Editing/TestSceneDistanceSnapGrid.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 20 +++++++++---------- .../Rulesets/Edit/IPositionSnapProvider.cs | 2 +- .../Compose/Components/DistanceSnapGrid.cs | 2 +- .../Compose/Components/Timeline/Timeline.cs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index 38779ab47b..f32a1a823e 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor set => InternalChild = value; } - public override IBindable DistanceSpacingMultiplier => throw new System.NotImplementedException(); + public override IBindable DistanceSpacingMultiplier => throw new System.NotImplementedException(); public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) { diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index c5829d5351..38a442d48b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -187,7 +187,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => (float)beat_length; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index cba6d7692d..69fd642143 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -167,7 +167,7 @@ namespace osu.Game.Tests.Visual.Editing public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => 10; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 948e1d770f..ab82fbad04 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -66,15 +66,15 @@ namespace osu.Game.Rulesets.Edit /// protected abstract bool SupportsDistanceSpacing { get; } - private readonly BindableFloat distanceSpacing = new BindableFloat + private readonly BindableDouble distanceSpacing = new BindableDouble { - Default = 1.0f, - MinValue = 0.1f, - MaxValue = 6.0f, - Precision = 0.01f, + Default = 1.0, + MinValue = 0.1, + MaxValue = 6.0, + Precision = 0.01, }; - public override IBindable DistanceSpacingMultiplier => distanceSpacing; + public override IBindable DistanceSpacingMultiplier => distanceSpacing; private SnappingToolboxContainer snappingToolboxContainer; @@ -161,11 +161,11 @@ namespace osu.Game.Rulesets.Edit }, }; - distanceSpacing.Value = (float)EditorBeatmap.BeatmapInfo.DistanceSpacing; + distanceSpacing.Value = EditorBeatmap.BeatmapInfo.DistanceSpacing; if (SupportsDistanceSpacing) { - ExpandableSlider distanceSpacingSlider; + ExpandableSlider> distanceSpacingSlider; AddInternal(snappingToolboxContainer = new SnappingToolboxContainer { @@ -173,7 +173,7 @@ namespace osu.Game.Rulesets.Edit Origin = Anchor.TopRight, Child = new EditorToolboxGroup("snapping") { - Child = distanceSpacingSlider = new ExpandableSlider + Child = distanceSpacingSlider = new ExpandableSlider> { Current = { BindTarget = distanceSpacing }, KeyboardStep = 0.01f, @@ -563,7 +563,7 @@ namespace osu.Game.Rulesets.Edit #region IPositionSnapProvider - public abstract IBindable DistanceSpacingMultiplier { get; } + public abstract IBindable DistanceSpacingMultiplier { get; } public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition); diff --git a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs index 1cfcb86e10..e4adbba47d 100644 --- a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Edit /// The spacing multiplier applied to beat snap distances. /// /// - IBindable DistanceSpacingMultiplier { get; } + IBindable DistanceSpacingMultiplier { get; } /// /// Given a position, find a valid time and position snap. diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index afbe83ec83..f9e4ef086c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private BindableBeatDivisor beatDivisor { get; set; } - private IBindable distanceSpacingMultiplier; + private IBindable distanceSpacingMultiplier; private readonly LayoutValue gridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); private readonly double? endTime; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index f3a328c6bc..8832c4e89c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -317,7 +317,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private double getTimeFromPosition(Vector2 localPosition) => (localPosition.X / Content.DrawWidth) * track.Length; - public IBindable DistanceSpacingMultiplier => throw new NotImplementedException(); + public IBindable DistanceSpacingMultiplier => throw new NotImplementedException(); public float GetBeatSnapDistanceAt(HitObject referenceObject) => throw new NotImplementedException(); From 8b30c847f9ab3829b8fc8bc0e5f944a217cba8e5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 16 Feb 2022 08:39:08 +0300 Subject: [PATCH 10/27] Update outdated bindable casts in tests --- osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs | 2 +- osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index 41304dcd24..aa0e35102e 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time)); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableFloat)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 23131668a0..13ce340362 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor }); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableFloat)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } From b66566e96d4f22d7e4351443ea8d999fd7f9bce7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 16 Feb 2022 10:35:57 +0300 Subject: [PATCH 11/27] Use explicit culture info rather than `null` --- osu.Game/Overlays/Settings/Sections/SizeSlider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index cc2c77adf2..26db1aa755 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Globalization; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; @@ -13,6 +14,6 @@ namespace osu.Game.Overlays.Settings.Sections internal class SizeSlider : OsuSliderBar where T : struct, IEquatable, IComparable, IConvertible, IFormattable { - public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", null); + public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo); } } From 70a93c0e7eb66c3316e5c4d0a38a96dc7ebc0db7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 24 Apr 2022 07:08:53 +0300 Subject: [PATCH 12/27] Move `DistanceSpacingMultiplier` bindable to its own `IDistanceSnapProvider` interface --- .../Editor/TestSceneManiaBeatSnapGrid.cs | 3 --- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 4 ++-- .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 4 ++-- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 17 +++++++++++++++++ osu.Game/Rulesets/Edit/IPositionSnapProvider.cs | 10 ++-------- .../Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 6 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index f32a1a823e..50be13c4e0 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Framework.Timing; @@ -99,8 +98,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor set => InternalChild = value; } - public override IBindable DistanceSpacingMultiplier => throw new System.NotImplementedException(); - public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) { throw new System.NotImplementedException(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index 38a442d48b..2ba30c5f74 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor [Cached] private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); - [Cached(typeof(IPositionSnapProvider))] + [Cached(typeof(IDistanceSnapProvider))] private readonly SnapProvider snapProvider = new SnapProvider(); private TestOsuDistanceSnapGrid grid; @@ -180,7 +180,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor } } - private class SnapProvider : IPositionSnapProvider + private class SnapProvider : IDistanceSnapProvider { public SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, null); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 69fd642143..b9cfa84a5d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Editing [Cached(typeof(EditorBeatmap))] private readonly EditorBeatmap editorBeatmap; - [Cached(typeof(IPositionSnapProvider))] + [Cached(typeof(IDistanceSnapProvider))] private readonly SnapProvider snapProvider = new SnapProvider(); public TestSceneDistanceSnapGrid() @@ -160,7 +160,7 @@ namespace osu.Game.Tests.Visual.Editing => (Vector2.Zero, 0); } - private class SnapProvider : IPositionSnapProvider + private class SnapProvider : IDistanceSnapProvider { public SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, null); diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs new file mode 100644 index 0000000000..70921a6170 --- /dev/null +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -0,0 +1,17 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Game.Beatmaps; + +namespace osu.Game.Rulesets.Edit +{ + public interface IDistanceSnapProvider : IPositionSnapProvider + { + /// + /// The spacing multiplier applied to beat snap distances. + /// + /// + IBindable DistanceSpacingMultiplier { get; } + } +} diff --git a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs index e4adbba47d..944619a3ca 100644 --- a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IPositionSnapProvider.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. -using osu.Framework.Bindables; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osuTK; @@ -10,12 +8,6 @@ namespace osu.Game.Rulesets.Edit { public interface IPositionSnapProvider { - /// - /// The spacing multiplier applied to beat snap distances. - /// - /// - IBindable DistanceSpacingMultiplier { get; } - /// /// Given a position, find a valid time and position snap. /// @@ -38,6 +30,8 @@ namespace osu.Game.Rulesets.Edit /// /// An object to be used as a reference point for this operation. /// The distance between two points residing in the timing point that are one beat length apart. + // todo: this, and other distance-related methods below it, should move to IDistanceSnapProvider. + // needs thought on how to properly share implementation, since not all composers inherit IDistanceSnapProvider. float GetBeatSnapDistanceAt(HitObject referenceObject); /// diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index f9e4ef086c..9dd6cec8ce 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected OsuColour Colours { get; private set; } [Resolved] - protected IPositionSnapProvider SnapProvider { get; private set; } + protected IDistanceSnapProvider SnapProvider { get; private set; } [Resolved] private EditorBeatmap beatmap { get; set; } From 8ed39009fd5301396d5d98be2a98c9dd6e3a3d87 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 24 Apr 2022 07:10:30 +0300 Subject: [PATCH 13/27] Encapsulate distance spacing control handling to a "distance toolbox composite" Encapsulated in a way which can allow further extensibility for the right-side area of toolboxes. --- .../Edit/CatchHitObjectComposer.cs | 5 +- .../Edit/ManiaHitObjectComposer.cs | 2 - .../Editor/TestSceneObjectObjectSnap.cs | 4 +- .../Editor/TestSceneSliderSnapping.cs | 3 +- .../Edit/OsuHitObjectComposer.cs | 12 +- .../Edit/OsuToolboxComposite.cs | 119 ++++++++++++++++++ .../Edit/TaikoHitObjectComposer.cs | 2 - .../Overlays/Settings/Sections/SizeSlider.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 99 +-------------- 9 files changed, 137 insertions(+), 111 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 19595de3b1..b3e6fe382a 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -24,6 +24,9 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit { + /// + /// todo: should inherit once it supports distance spacing properly. + /// public class CatchHitObjectComposer : HitObjectComposer { private const float distance_snap_radius = 50; @@ -32,8 +35,6 @@ namespace osu.Game.Rulesets.Catch.Edit private readonly Bindable distanceSnapToggle = new Bindable(); - protected override bool SupportsDistanceSpacing => false; - private InputManager inputManager; public CatchHitObjectComposer(CatchRuleset ruleset) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 5752f9f014..2baec95c94 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -26,8 +26,6 @@ namespace osu.Game.Rulesets.Mania.Edit private ManiaBeatSnapGrid beatSnapGrid; private InputManager inputManager; - protected override bool SupportsDistanceSpacing => false; - public ManiaHitObjectComposer(Ruleset ruleset) : base(ruleset) { diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index aa0e35102e..954bb53dd5 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -7,7 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time)); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 13ce340362..2632e556c6 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -11,7 +11,6 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Input.Bindings; -using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; @@ -69,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor }); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index e7eabdc748..a52c916ca0 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -24,9 +24,12 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuHitObjectComposer : HitObjectComposer + [Cached(typeof(IDistanceSnapProvider))] + public class OsuHitObjectComposer : HitObjectComposer, IDistanceSnapProvider { - protected override bool SupportsDistanceSpacing => true; + private OsuToolboxComposite osuToolboxComposite; + + public IBindable DistanceSpacingMultiplier => osuToolboxComposite.DistanceSpacing; public OsuHitObjectComposer(Ruleset ruleset) : base(ruleset) @@ -76,6 +79,8 @@ namespace osu.Game.Rulesets.Osu.Edit } }); + AddInternal(osuToolboxComposite = new OsuToolboxComposite()); + selectedHitObjects = EditorBeatmap.SelectedHitObjects.GetBoundCopy(); selectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid(); @@ -130,6 +135,9 @@ namespace osu.Game.Rulesets.Osu.Edit } } + public override float GetBeatSnapDistanceAt(HitObject referenceObject) + => (float)(base.GetBeatSnapDistanceAt(referenceObject) * DistanceSpacingMultiplier.Value); + public override SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) { if (snapToVisibleBlueprints(screenSpacePosition, out var snapResult)) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs new file mode 100644 index 0000000000..b0298e4034 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs @@ -0,0 +1,119 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings.Sections; +using osu.Game.Rulesets.Edit; +using osu.Game.Screens.Edit; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Rulesets.Osu.Edit +{ + /// + /// A toolbox composite for osu!-specific controls. + /// + // todo: once catch supports distance spacing, the control here should move out to a base "DistancingRulesetToolboxComposite" class or something better. + public class OsuToolboxComposite : CompositeDrawable + { + private ExpandingToolboxContainer expandingContainer; + private ExpandableSlider> distanceSpacingSlider; + + private readonly Bindable distanceSpacing = new BindableDouble(1.0) + { + MinValue = 0.1, + MaxValue = 6.0, + Precision = 0.01, + }; + + public IBindable DistanceSpacing => distanceSpacing; + + private bool distanceSpacingScrollActive; + + [Resolved] + private EditorBeatmap editorBeatmap { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = expandingContainer = new ExpandingToolboxContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Child = new EditorToolboxGroup("snapping") + { + Child = distanceSpacingSlider = new ExpandableSlider> + { + Current = { BindTarget = distanceSpacing }, + KeyboardStep = 0.1f, + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + distanceSpacing.Value = editorBeatmap.BeatmapInfo.DistanceSpacing; + distanceSpacing.BindValueChanged(v => + { + distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; + distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; + editorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; + }, true); + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.AltPressed && e.Key == Key.D && !e.Repeat) + { + expandingContainer.Expanded.Value = true; + distanceSpacingScrollActive = true; + return true; + } + + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + if (distanceSpacingScrollActive && (!e.AltPressed || e.Key == Key.D)) + { + expandingContainer.Expanded.Value = false; + distanceSpacingScrollActive = false; + } + } + + protected override bool OnScroll(ScrollEvent e) + { + if (distanceSpacingScrollActive) + { + distanceSpacing.Value += e.ScrollDelta.Y * (e.IsPrecise ? 0.01f : 0.1f); + return true; + } + + return base.OnScroll(e); + } + + private class ExpandingToolboxContainer : ExpandingContainer + { + public ExpandingToolboxContainer() + : base(130, 250) + { + RelativeSizeAxes = Axes.Y; + Padding = new MarginPadding { Left = 10 }; + + FillFlow.Spacing = new Vector2(10); + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index af9bc6c3a3..161799c980 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -11,8 +11,6 @@ namespace osu.Game.Rulesets.Taiko.Edit { public class TaikoHitObjectComposer : HitObjectComposer { - protected override bool SupportsDistanceSpacing => false; - public TaikoHitObjectComposer(TaikoRuleset ruleset) : base(ruleset) { diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index 26db1aa755..c8a46162af 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections /// /// A slider intended to show a "size" multiplier number, where 1x is 1.0. /// - internal class SizeSlider : OsuSliderBar + public class SizeSlider : OsuSliderBar where T : struct, IEquatable, IComparable, IConvertible, IFormattable { public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index ab82fbad04..8d2bd1e5d1 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -14,8 +14,6 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Settings.Sections; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -58,26 +56,6 @@ namespace osu.Game.Rulesets.Edit [Resolved] protected IBeatSnapProvider BeatSnapProvider { get; private set; } - /// - /// Whether this composer supports a "distance spacing" multiplier for distance snap grids. - /// - /// - /// Setting this to displays a "distance spacing" slider and allows this composer to configure the value of . - /// - protected abstract bool SupportsDistanceSpacing { get; } - - private readonly BindableDouble distanceSpacing = new BindableDouble - { - Default = 1.0, - MinValue = 0.1, - MaxValue = 6.0, - Precision = 0.01, - }; - - public override IBindable DistanceSpacingMultiplier => distanceSpacing; - - private SnappingToolboxContainer snappingToolboxContainer; - protected ComposeBlueprintContainer BlueprintContainer { get; private set; } private DrawableEditorRulesetWrapper drawableRulesetWrapper; @@ -161,36 +139,6 @@ namespace osu.Game.Rulesets.Edit }, }; - distanceSpacing.Value = EditorBeatmap.BeatmapInfo.DistanceSpacing; - - if (SupportsDistanceSpacing) - { - ExpandableSlider> distanceSpacingSlider; - - AddInternal(snappingToolboxContainer = new SnappingToolboxContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Child = new EditorToolboxGroup("snapping") - { - Child = distanceSpacingSlider = new ExpandableSlider> - { - Current = { BindTarget = distanceSpacing }, - KeyboardStep = 0.01f, - } - } - }); - - distanceSpacing.BindValueChanged(v => - { - distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; - distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; - EditorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; - }, true); - } - else - distanceSpacing.Disabled = true; - toolboxCollection.Items = CompositionTools .Prepend(new SelectTool()) .Select(t => new RadioButton(t.Name, () => toolSelected(t), t.CreateIcon)) @@ -265,17 +213,8 @@ namespace osu.Game.Rulesets.Edit #region Tool selection logic - private bool distanceSpacingScrollActive; - protected override bool OnKeyDown(KeyDownEvent e) { - if (SupportsDistanceSpacing && e.AltPressed && e.Key == Key.D && !e.Repeat) - { - snappingToolboxContainer.Expanded.Value = true; - distanceSpacingScrollActive = true; - return true; - } - if (e.ControlPressed || e.AltPressed || e.SuperPressed) return false; @@ -305,28 +244,6 @@ namespace osu.Game.Rulesets.Edit return base.OnKeyDown(e); } - protected override void OnKeyUp(KeyUpEvent e) - { - if (distanceSpacingScrollActive && (e.Key == Key.AltLeft || e.Key == Key.AltRight || e.Key == Key.D)) - { - snappingToolboxContainer.Expanded.Value = false; - distanceSpacingScrollActive = false; - } - - base.OnKeyUp(e); - } - - protected override bool OnScroll(ScrollEvent e) - { - if (distanceSpacingScrollActive) - { - distanceSpacing.Value += e.ScrollDelta.Y * (e.IsPrecise ? 0.01f : 0.1f); - return true; - } - - return base.OnScroll(e); - } - private bool checkLeftToggleFromKey(Key key, out int index) { if (key < Key.Number1 || key > Key.Number9) @@ -468,7 +385,7 @@ namespace osu.Game.Rulesets.Edit public override float GetBeatSnapDistanceAt(HitObject referenceObject) { - return (float)(100 * referenceObject.DifficultyControlPoint.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier * distanceSpacing.Value / BeatSnapProvider.BeatDivisor); + return (float)(100 * referenceObject.DifficultyControlPoint.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier / BeatSnapProvider.BeatDivisor); } public override float DurationToDistance(HitObject referenceObject, double duration) @@ -517,18 +434,6 @@ namespace osu.Game.Rulesets.Edit FillFlow.Spacing = new Vector2(10); } } - - private class SnappingToolboxContainer : ExpandingContainer - { - public SnappingToolboxContainer() - : base(130, 250) - { - RelativeSizeAxes = Axes.Y; - Padding = new MarginPadding { Left = 10 }; - - FillFlow.Spacing = new Vector2(10); - } - } } /// @@ -563,8 +468,6 @@ namespace osu.Game.Rulesets.Edit #region IPositionSnapProvider - public abstract IBindable DistanceSpacingMultiplier { get; } - public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition); public virtual SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) => From 0738cd028f5824cf6f9a0511ee9321d8e6876000 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 24 Apr 2022 08:53:10 +0300 Subject: [PATCH 14/27] Give snapping toolbox enough hover delay for interaction with expand button With 0 delay, if the `SettingsToolboxGroup` has been contracted via button, there's no chance to be able to expand it via button again. This is temporary at best just to keep things working somewhat, not sure if the expansion logic will still be required in editor redesign, so deciding to roll with it for now. --- osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs index b0298e4034..542f98207e 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs @@ -106,6 +106,8 @@ namespace osu.Game.Rulesets.Osu.Edit private class ExpandingToolboxContainer : ExpandingContainer { + protected override double HoverExpansionDelay => 250; + public ExpandingToolboxContainer() : base(130, 250) { From 66c730c382cdd9ab74f74053e043b385e17586a6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 27 Apr 2022 17:11:23 +0300 Subject: [PATCH 15/27] Change distance spacing keybind to Ctrl+Alt --- osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs | 5 ++--- osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs index 542f98207e..17232db509 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs @@ -12,7 +12,6 @@ using osu.Game.Overlays.Settings.Sections; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osuTK; -using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit { @@ -74,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Edit protected override bool OnKeyDown(KeyDownEvent e) { - if (e.AltPressed && e.Key == Key.D && !e.Repeat) + if (e.ControlPressed && e.AltPressed && !e.Repeat) { expandingContainer.Expanded.Value = true; distanceSpacingScrollActive = true; @@ -86,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Edit protected override void OnKeyUp(KeyUpEvent e) { - if (distanceSpacingScrollActive && (!e.AltPressed || e.Key == Key.D)) + if (distanceSpacingScrollActive && (!e.AltPressed || !e.ControlPressed)) { expandingContainer.Expanded.Value = false; distanceSpacingScrollActive = false; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index d542732e19..7039d7d8a4 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -95,14 +95,14 @@ namespace osu.Game.Tests.Visual.Editing AddStep("retrieve original spacing", () => originalSpacing = (float)editorBeatmap.BeatmapInfo.DistanceSpacing); + AddStep("hold ctrl", () => InputManager.PressKey(Key.LControl)); AddStep("hold alt", () => InputManager.PressKey(Key.LAlt)); - AddStep("hold D", () => InputManager.PressKey(Key.D)); AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); AddAssert("distance spacing increased by 0.5", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.5f)); AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); - AddStep("release D", () => InputManager.ReleaseKey(Key.D)); + AddStep("release ctrl", () => InputManager.ReleaseKey(Key.LControl)); } public class EditorBeatmapContainer : Container From 59cf3ff50fad705e477d8b00c6fcfed55550e387 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 05:48:45 +0300 Subject: [PATCH 16/27] Move distancing methods from `IPositionSnapProvider` to `IDistanceSnapProvider` --- .../Editor/TestSceneManiaBeatSnapGrid.cs | 26 ----------- .../Components/PathControlPointVisualiser.cs | 2 +- .../Sliders/SliderPlacementBlueprint.cs | 4 +- .../Sliders/SliderSelectionBlueprint.cs | 6 +-- .../Edit/OsuSelectionHandler.cs | 6 +-- .../Rulesets/Edit/IDistanceSnapProvider.cs | 41 ++++++++++++++++++ .../Rulesets/Edit/IPositionSnapProvider.cs | 43 ------------------- .../Rulesets/Objects/SliderPathExtensions.cs | 2 +- .../Compose/Components/Timeline/Timeline.cs | 13 ------ 9 files changed, 51 insertions(+), 92 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index 50be13c4e0..2e55f86bb6 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -13,7 +13,6 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Edit; using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; @@ -107,30 +106,5 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor { throw new System.NotImplementedException(); } - - public override float GetBeatSnapDistanceAt(HitObject referenceObject) - { - throw new System.NotImplementedException(); - } - - public override float DurationToDistance(HitObject referenceObject, double duration) - { - throw new System.NotImplementedException(); - } - - public override double DistanceToDuration(HitObject referenceObject, float distance) - { - throw new System.NotImplementedException(); - } - - public override double GetSnappedDurationFromDistance(HitObject referenceObject, float distance) - { - throw new System.NotImplementedException(); - } - - public override float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance) - { - throw new System.NotImplementedException(); - } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index ae4141073e..5de614722f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components public Action> RemoveControlPointsRequested; [Resolved(CanBeNull = true)] - private IPositionSnapProvider snapProvider { get; set; } + private IDistanceSnapProvider snapProvider { get; set; } public PathControlPointVisualiser(Slider slider, bool allowSelection) { diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index b868c9a7ee..73a4ea5434 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private int currentSegmentLength; [Resolved(CanBeNull = true)] - private HitObjectComposer composer { get; set; } + private IDistanceSnapProvider snapProvider { get; set; } public SliderPlacementBlueprint() : base(new Objects.Slider()) @@ -220,7 +220,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateSlider() { - HitObject.Path.ExpectedDistance.Value = composer?.GetSnappedDistanceFromDistance(HitObject, (float)HitObject.Path.CalculatedDistance) ?? (float)HitObject.Path.CalculatedDistance; + HitObject.Path.ExpectedDistance.Value = snapProvider?.GetSnappedDistanceFromDistance(HitObject, (float)HitObject.Path.CalculatedDistance) ?? (float)HitObject.Path.CalculatedDistance; bodyPiece.UpdateFrom(HitObject); headCirclePiece.UpdateFrom(HitObject.HeadCircle); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 6cf2a493a9..a019f2fb64 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected PathControlPointVisualiser ControlPointVisualiser { get; private set; } [Resolved(CanBeNull = true)] - private HitObjectComposer composer { get; set; } + private IDistanceSnapProvider snapProvider { get; set; } [Resolved(CanBeNull = true)] private IPlacementHandler placementHandler { get; set; } @@ -208,7 +208,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders // Move the control points from the insertion index onwards to make room for the insertion controlPoints.Insert(insertionIndex, pathControlPoint); - HitObject.SnapTo(composer); + HitObject.SnapTo(snapProvider); return pathControlPoint; } @@ -230,7 +230,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders } // Snap the slider to the current beat divisor before checking length validity. - HitObject.SnapTo(composer); + HitObject.SnapTo(snapProvider); // If there are 0 or 1 remaining control points, or the slider has an invalid length, it is in a degenerate form and should be deleted if (controlPoints.Count <= 1 || !HitObject.Path.HasValidLength) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index efbac5439c..70c60ab635 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Edit public class OsuSelectionHandler : EditorSelectionHandler { [Resolved(CanBeNull = true)] - private IPositionSnapProvider? positionSnapProvider { get; set; } + private IDistanceSnapProvider? snapProvider { get; set; } /// /// During a transform, the initial origin is stored so it can be used throughout the operation. @@ -206,7 +206,7 @@ namespace osu.Game.Rulesets.Osu.Edit // Snap the slider's length to the current beat divisor // to calculate the final resulting duration / bounding box before the final checks. - slider.SnapTo(positionSnapProvider); + slider.SnapTo(snapProvider); //if sliderhead or sliderend end up outside playfield, revert scaling. Quad scaledQuad = getSurroundingQuad(new OsuHitObject[] { slider }); @@ -219,7 +219,7 @@ namespace osu.Game.Rulesets.Osu.Edit point.Position = oldControlPoints.Dequeue(); // Snap the slider's length again to undo the potentially-invalid length applied by the previous snap. - slider.SnapTo(positionSnapProvider); + slider.SnapTo(snapProvider); } private void scaleHitObjects(OsuHitObject[] hitObjects, Anchor reference, Vector2 scale) diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index 70921a6170..c6e866561e 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -3,6 +3,7 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Edit { @@ -13,5 +14,45 @@ namespace osu.Game.Rulesets.Edit /// /// IBindable DistanceSpacingMultiplier { get; } + + /// + /// Retrieves the distance between two points within a timing point that are one beat length apart. + /// + /// An object to be used as a reference point for this operation. + /// The distance between two points residing in the timing point that are one beat length apart. + float GetBeatSnapDistanceAt(HitObject referenceObject); + + /// + /// Converts a duration to a distance. + /// + /// An object to be used as a reference point for this operation. + /// The duration to convert. + /// A value that represents as a distance in the timing point. + float DurationToDistance(HitObject referenceObject, double duration); + + /// + /// Converts a distance to a duration. + /// + /// An object to be used as a reference point for this operation. + /// The distance to convert. + /// A value that represents as a duration in the timing point. + double DistanceToDuration(HitObject referenceObject, float distance); + + /// + /// Converts a distance to a snapped duration. + /// + /// An object to be used as a reference point for this operation. + /// The distance to convert. + /// A value that represents as a duration snapped to the closest beat of the timing point. + double GetSnappedDurationFromDistance(HitObject referenceObject, float distance); + + /// + /// Converts an unsnapped distance to a snapped distance. + /// The returned distance will always be floored (as to never exceed the provided . + /// + /// An object to be used as a reference point for this operation. + /// The distance to convert. + /// A value that represents snapped to the closest beat of the timing point. + float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance); } } diff --git a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs index 944619a3ca..8a179ed424 100644 --- a/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IPositionSnapProvider.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Rulesets.Objects; using osuTK; namespace osu.Game.Rulesets.Edit @@ -24,47 +23,5 @@ namespace osu.Game.Rulesets.Edit /// The screen-space position to be snapped. /// The position post-snapping. Time will always be null. SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition); - - /// - /// Retrieves the distance between two points within a timing point that are one beat length apart. - /// - /// An object to be used as a reference point for this operation. - /// The distance between two points residing in the timing point that are one beat length apart. - // todo: this, and other distance-related methods below it, should move to IDistanceSnapProvider. - // needs thought on how to properly share implementation, since not all composers inherit IDistanceSnapProvider. - float GetBeatSnapDistanceAt(HitObject referenceObject); - - /// - /// Converts a duration to a distance. - /// - /// An object to be used as a reference point for this operation. - /// The duration to convert. - /// A value that represents as a distance in the timing point. - float DurationToDistance(HitObject referenceObject, double duration); - - /// - /// Converts a distance to a duration. - /// - /// An object to be used as a reference point for this operation. - /// The distance to convert. - /// A value that represents as a duration in the timing point. - double DistanceToDuration(HitObject referenceObject, float distance); - - /// - /// Converts a distance to a snapped duration. - /// - /// An object to be used as a reference point for this operation. - /// The distance to convert. - /// A value that represents as a duration snapped to the closest beat of the timing point. - double GetSnappedDurationFromDistance(HitObject referenceObject, float distance); - - /// - /// Converts an unsnapped distance to a snapped distance. - /// The returned distance will always be floored (as to never exceed the provided . - /// - /// An object to be used as a reference point for this operation. - /// The distance to convert. - /// A value that represents snapped to the closest beat of the timing point. - float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance); } } diff --git a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs index ba614900c0..3100d26a55 100644 --- a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs +++ b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Objects /// /// Snaps the provided 's duration using the . /// - public static void SnapTo(this THitObject hitObject, IPositionSnapProvider? snapProvider) + public static void SnapTo(this THitObject hitObject, IDistanceSnapProvider? snapProvider) where THitObject : HitObject, IHasPath { hitObject.Path.ExpectedDistance.Value = snapProvider?.GetSnappedDistanceFromDistance(hitObject, (float)hitObject.Path.CalculatedDistance) ?? hitObject.Path.CalculatedDistance; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 8832c4e89c..c2b2bdb861 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline @@ -316,17 +315,5 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private double getTimeFromPosition(Vector2 localPosition) => (localPosition.X / Content.DrawWidth) * track.Length; - - public IBindable DistanceSpacingMultiplier => throw new NotImplementedException(); - - public float GetBeatSnapDistanceAt(HitObject referenceObject) => throw new NotImplementedException(); - - public float DurationToDistance(HitObject referenceObject, double duration) => throw new NotImplementedException(); - - public double DistanceToDuration(HitObject referenceObject, float distance) => throw new NotImplementedException(); - - public double GetSnappedDurationFromDistance(HitObject referenceObject, float distance) => throw new NotImplementedException(); - - public float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance) => throw new NotImplementedException(); } } From 835898dd30ae70170a6670178d19397d7a057361 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 05:49:37 +0300 Subject: [PATCH 17/27] Introduce `DistancedHitObjectComposer` and supersede `OsuToolboxComposite` --- .../Editor/TestSceneObjectObjectSnap.cs | 4 +- .../Editor/TestSceneSliderSnapping.cs | 3 +- .../Edit/OsuHitObjectComposer.cs | 12 +- .../Edit/OsuToolboxComposite.cs | 120 ------------- .../Edit/DistancedHitObjectComposer.cs | 158 ++++++++++++++++++ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 48 ------ 6 files changed, 163 insertions(+), 182 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs create mode 100644 osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index 954bb53dd5..dfb6ecfcae 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -7,7 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Osu.Edit; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time)); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 2632e556c6..702e2216ac 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -11,6 +11,7 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; @@ -68,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor }); AddStep("set distance spacing to 1", () => { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; + var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; distanceSpacing.Value = 1; }); } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index a52c916ca0..bd26a99e51 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -24,13 +24,8 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit { - [Cached(typeof(IDistanceSnapProvider))] - public class OsuHitObjectComposer : HitObjectComposer, IDistanceSnapProvider + public class OsuHitObjectComposer : DistancedHitObjectComposer { - private OsuToolboxComposite osuToolboxComposite; - - public IBindable DistanceSpacingMultiplier => osuToolboxComposite.DistanceSpacing; - public OsuHitObjectComposer(Ruleset ruleset) : base(ruleset) { @@ -79,8 +74,6 @@ namespace osu.Game.Rulesets.Osu.Edit } }); - AddInternal(osuToolboxComposite = new OsuToolboxComposite()); - selectedHitObjects = EditorBeatmap.SelectedHitObjects.GetBoundCopy(); selectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid(); @@ -135,9 +128,6 @@ namespace osu.Game.Rulesets.Osu.Edit } } - public override float GetBeatSnapDistanceAt(HitObject referenceObject) - => (float)(base.GetBeatSnapDistanceAt(referenceObject) * DistanceSpacingMultiplier.Value); - public override SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) { if (snapToVisibleBlueprints(screenSpacePosition, out var snapResult)) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs b/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs deleted file mode 100644 index 17232db509..0000000000 --- a/osu.Game.Rulesets.Osu/Edit/OsuToolboxComposite.cs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Settings.Sections; -using osu.Game.Rulesets.Edit; -using osu.Game.Screens.Edit; -using osuTK; - -namespace osu.Game.Rulesets.Osu.Edit -{ - /// - /// A toolbox composite for osu!-specific controls. - /// - // todo: once catch supports distance spacing, the control here should move out to a base "DistancingRulesetToolboxComposite" class or something better. - public class OsuToolboxComposite : CompositeDrawable - { - private ExpandingToolboxContainer expandingContainer; - private ExpandableSlider> distanceSpacingSlider; - - private readonly Bindable distanceSpacing = new BindableDouble(1.0) - { - MinValue = 0.1, - MaxValue = 6.0, - Precision = 0.01, - }; - - public IBindable DistanceSpacing => distanceSpacing; - - private bool distanceSpacingScrollActive; - - [Resolved] - private EditorBeatmap editorBeatmap { get; set; } - - [BackgroundDependencyLoader] - private void load() - { - RelativeSizeAxes = Axes.Both; - - InternalChild = expandingContainer = new ExpandingToolboxContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Child = new EditorToolboxGroup("snapping") - { - Child = distanceSpacingSlider = new ExpandableSlider> - { - Current = { BindTarget = distanceSpacing }, - KeyboardStep = 0.1f, - } - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - distanceSpacing.Value = editorBeatmap.BeatmapInfo.DistanceSpacing; - distanceSpacing.BindValueChanged(v => - { - distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; - distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; - editorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; - }, true); - } - - protected override bool OnKeyDown(KeyDownEvent e) - { - if (e.ControlPressed && e.AltPressed && !e.Repeat) - { - expandingContainer.Expanded.Value = true; - distanceSpacingScrollActive = true; - return true; - } - - return base.OnKeyDown(e); - } - - protected override void OnKeyUp(KeyUpEvent e) - { - if (distanceSpacingScrollActive && (!e.AltPressed || !e.ControlPressed)) - { - expandingContainer.Expanded.Value = false; - distanceSpacingScrollActive = false; - } - } - - protected override bool OnScroll(ScrollEvent e) - { - if (distanceSpacingScrollActive) - { - distanceSpacing.Value += e.ScrollDelta.Y * (e.IsPrecise ? 0.01f : 0.1f); - return true; - } - - return base.OnScroll(e); - } - - private class ExpandingToolboxContainer : ExpandingContainer - { - protected override double HoverExpansionDelay => 250; - - public ExpandingToolboxContainer() - : base(130, 250) - { - RelativeSizeAxes = Axes.Y; - Padding = new MarginPadding { Left = 10 }; - - FillFlow.Spacing = new Vector2(10); - } - } - } -} diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs new file mode 100644 index 0000000000..a3624f6d77 --- /dev/null +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -0,0 +1,158 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings.Sections; +using osu.Game.Rulesets.Objects; +using osuTK; + +namespace osu.Game.Rulesets.Edit +{ + /// + /// Represents a for rulesets with the concept of distances between objects. + /// + /// The base type of supported objects. + [Cached(typeof(IDistanceSnapProvider))] + public abstract class DistancedHitObjectComposer : HitObjectComposer, IDistanceSnapProvider + where TObject : HitObject + { + protected Bindable DistanceSpacingMultiplier { get; } = new BindableDouble(1.0) + { + MinValue = 0.1, + MaxValue = 6.0, + Precision = 0.01, + }; + + IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; + + protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } + + private ExpandableSlider> distanceSpacingSlider; + private bool distanceSpacingScrollActive; + + protected DistancedHitObjectComposer(Ruleset ruleset) + : base(ruleset) + { + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(RightSideToolboxContainer = new ExpandingToolboxContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Child = new EditorToolboxGroup("snapping") + { + Child = distanceSpacingSlider = new ExpandableSlider> + { + Current = { BindTarget = DistanceSpacingMultiplier }, + KeyboardStep = 0.1f, + } + } + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + DistanceSpacingMultiplier.Value = EditorBeatmap.BeatmapInfo.DistanceSpacing; + DistanceSpacingMultiplier.BindValueChanged(v => + { + distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; + distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; + EditorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; + }, true); + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.ControlPressed && e.AltPressed && !e.Repeat) + { + RightSideToolboxContainer.Expanded.Value = true; + distanceSpacingScrollActive = true; + return true; + } + + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + if (distanceSpacingScrollActive && (!e.AltPressed || !e.ControlPressed)) + { + RightSideToolboxContainer.Expanded.Value = false; + distanceSpacingScrollActive = false; + } + } + + protected override bool OnScroll(ScrollEvent e) + { + if (distanceSpacingScrollActive) + { + DistanceSpacingMultiplier.Value += e.ScrollDelta.Y * (e.IsPrecise ? 0.01f : 0.1f); + return true; + } + + return base.OnScroll(e); + } + + public virtual float GetBeatSnapDistanceAt(HitObject referenceObject) + { + return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * referenceObject.DifficultyControlPoint.SliderVelocity * DistanceSpacingMultiplier.Value / BeatSnapProvider.BeatDivisor); + } + + public virtual float DurationToDistance(HitObject referenceObject, double duration) + { + double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); + return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceObject)); + } + + public virtual double DistanceToDuration(HitObject referenceObject, float distance) + { + double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); + return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; + } + + public virtual double GetSnappedDurationFromDistance(HitObject referenceObject, float distance) + => BeatSnapProvider.SnapTime(referenceObject.StartTime + DistanceToDuration(referenceObject, distance), referenceObject.StartTime) - referenceObject.StartTime; + + public virtual float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance) + { + double startTime = referenceObject.StartTime; + + double actualDuration = startTime + DistanceToDuration(referenceObject, distance); + + double snappedEndTime = BeatSnapProvider.SnapTime(actualDuration, startTime); + + double beatLength = BeatSnapProvider.GetBeatLengthAtTime(startTime); + + // we don't want to exceed the actual duration and snap to a point in the future. + // as we are snapping to beat length via SnapTime (which will round-to-nearest), check for snapping in the forward direction and reverse it. + if (snappedEndTime > actualDuration + 1) + snappedEndTime -= beatLength; + + return DurationToDistance(referenceObject, snappedEndTime - startTime); + } + + protected class ExpandingToolboxContainer : ExpandingContainer + { + protected override double HoverExpansionDelay => 250; + + public ExpandingToolboxContainer() + : base(130, 250) + { + RelativeSizeAxes = Axes.Y; + Padding = new MarginPadding { Left = 10 }; + + FillFlow.Spacing = new Vector2(10); + } + } + } +} diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 8d2bd1e5d1..9fc332d726 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -383,44 +383,6 @@ namespace osu.Game.Rulesets.Edit return new SnapResult(screenSpacePosition, targetTime, playfield); } - public override float GetBeatSnapDistanceAt(HitObject referenceObject) - { - return (float)(100 * referenceObject.DifficultyControlPoint.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier / BeatSnapProvider.BeatDivisor); - } - - public override float DurationToDistance(HitObject referenceObject, double duration) - { - double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return (float)(duration / beatLength * GetBeatSnapDistanceAt(referenceObject)); - } - - public override double DistanceToDuration(HitObject referenceObject, float distance) - { - double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; - } - - public override double GetSnappedDurationFromDistance(HitObject referenceObject, float distance) - => BeatSnapProvider.SnapTime(referenceObject.StartTime + DistanceToDuration(referenceObject, distance), referenceObject.StartTime) - referenceObject.StartTime; - - public override float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance) - { - double startTime = referenceObject.StartTime; - - double actualDuration = startTime + DistanceToDuration(referenceObject, distance); - - double snappedEndTime = BeatSnapProvider.SnapTime(actualDuration, startTime); - - double beatLength = BeatSnapProvider.GetBeatLengthAtTime(startTime); - - // we don't want to exceed the actual duration and snap to a point in the future. - // as we are snapping to beat length via SnapTime (which will round-to-nearest), check for snapping in the forward direction and reverse it. - if (snappedEndTime > actualDuration + 1) - snappedEndTime -= beatLength; - - return DurationToDistance(referenceObject, snappedEndTime - startTime); - } - #endregion private class LeftToolboxFlow : ExpandingButtonContainer @@ -473,16 +435,6 @@ namespace osu.Game.Rulesets.Edit public virtual SnapResult SnapScreenSpacePositionToValidPosition(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, null); - public abstract float GetBeatSnapDistanceAt(HitObject referenceObject); - - public abstract float DurationToDistance(HitObject referenceObject, double duration); - - public abstract double DistanceToDuration(HitObject referenceObject, float distance); - - public abstract double GetSnappedDurationFromDistance(HitObject referenceObject, float distance); - - public abstract float GetSnappedDistanceFromDistance(HitObject referenceObject, float distance); - #endregion } } From bfc6bfc91b19a1fc9fb57518e490b81d9c09b8c3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 05:50:55 +0300 Subject: [PATCH 18/27] Let `CatchHitObjectComposer` inherit from `DistancedHitObjectComposer` and hide control --- .../Edit/CatchHitObjectComposer.cs | 9 +++++---- .../Edit/DistancedHitObjectComposer.cs | 20 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index b3e6fe382a..a90b0d3e89 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -24,10 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit { - /// - /// todo: should inherit once it supports distance spacing properly. - /// - public class CatchHitObjectComposer : HitObjectComposer + public class CatchHitObjectComposer : DistancedHitObjectComposer { private const float distance_snap_radius = 50; @@ -45,6 +42,10 @@ namespace osu.Game.Rulesets.Catch.Edit [BackgroundDependencyLoader] private void load() { + // todo: enable distance spacing once catch supports it. + RightSideToolboxContainer.Alpha = 0; + DistanceSpacingMultiplier.Disabled = true; + LayerBelowRuleset.Add(new PlayfieldBorder { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index a3624f6d77..d0c9babf24 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Edit { AddInternal(RightSideToolboxContainer = new ExpandingToolboxContainer { + Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Child = new EditorToolboxGroup("snapping") @@ -62,18 +63,21 @@ namespace osu.Game.Rulesets.Edit { base.LoadComplete(); - DistanceSpacingMultiplier.Value = EditorBeatmap.BeatmapInfo.DistanceSpacing; - DistanceSpacingMultiplier.BindValueChanged(v => + if (!DistanceSpacingMultiplier.Disabled) { - distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; - distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; - EditorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; - }, true); + DistanceSpacingMultiplier.Value = EditorBeatmap.BeatmapInfo.DistanceSpacing; + DistanceSpacingMultiplier.BindValueChanged(v => + { + distanceSpacingSlider.ContractedLabelText = $"D. S. ({v.NewValue:0.##x})"; + distanceSpacingSlider.ExpandedLabelText = $"Distance Spacing ({v.NewValue:0.##x})"; + EditorBeatmap.BeatmapInfo.DistanceSpacing = v.NewValue; + }, true); + } } protected override bool OnKeyDown(KeyDownEvent e) { - if (e.ControlPressed && e.AltPressed && !e.Repeat) + if (!DistanceSpacingMultiplier.Disabled && e.ControlPressed && e.AltPressed && !e.Repeat) { RightSideToolboxContainer.Expanded.Value = true; distanceSpacingScrollActive = true; @@ -85,7 +89,7 @@ namespace osu.Game.Rulesets.Edit protected override void OnKeyUp(KeyUpEvent e) { - if (distanceSpacingScrollActive && (!e.AltPressed || !e.ControlPressed)) + if (!DistanceSpacingMultiplier.Disabled && distanceSpacingScrollActive && (!e.AltPressed || !e.ControlPressed)) { RightSideToolboxContainer.Expanded.Value = false; distanceSpacingScrollActive = false; From a5defbe4961b06d37a8a6c7f834196e00f63a806 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 06:44:02 +0300 Subject: [PATCH 19/27] Keep distance spacing reset to one on test scenes with slider snapping for now --- .../Editor/TestSceneObjectObjectSnap.cs | 12 ++++-------- .../Editor/TestSceneSliderSnapping.cs | 10 ++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index dfb6ecfcae..21ba1e647d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -3,11 +3,9 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Bindables; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Tests.Beatmaps; @@ -21,18 +19,16 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { private OsuPlayfield playfield; - protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false); + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false) + { + BeatmapInfo = { DistanceSpacing = 1 } + }; public override void SetUpSteps() { base.SetUpSteps(); AddStep("get playfield", () => playfield = Editor.ChildrenOfType().First()); AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time)); - AddStep("set distance spacing to 1", () => - { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; - distanceSpacing.Value = 1; - }); } [TestCase(true)] diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 702e2216ac..4833266dca 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -4,14 +4,12 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Input.Events; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Input.Bindings; -using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; @@ -38,7 +36,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor controlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); return new TestBeatmap(ruleset, false) { - ControlPointInfo = controlPointInfo + ControlPointInfo = controlPointInfo, + BeatmapInfo = { DistanceSpacing = 1 }, }; } @@ -67,11 +66,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor var beatDivisor = Editor.Dependencies.Get(); beatDivisor.Value = 1; }); - AddStep("set distance spacing to 1", () => - { - var distanceSpacing = (BindableDouble)Editor.ChildrenOfType().Single().DistanceSpacingMultiplier; - distanceSpacing.Value = 1; - }); } [Test] From 71533808e9958f7470c407750cc34cdc0a014804 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 06:46:20 +0300 Subject: [PATCH 20/27] Add test case for `DistanceSpacingMultiplier` in distance snapping test scene --- .../TestSceneHitObjectComposerDistanceSnapping.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index d9312cb7ae..e2ff45c431 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; @@ -70,7 +71,7 @@ namespace osu.Game.Tests.Editing [TestCase(2)] public void TestSliderMultiplier(float multiplier) { - AddStep($"set multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); + AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); assertSnapDistance(100 * multiplier); } @@ -88,6 +89,15 @@ namespace osu.Game.Tests.Editing }); } + [TestCase(1)] + [TestCase(2)] + public void TestDistanceSpacingMultiplier(float multiplier) + { + AddStep($"set distance spacing = {multiplier}", () => composer.DistanceSpacingMultiplier.Value = multiplier); + + assertSnapDistance(100 * multiplier); + } + [TestCase(1)] [TestCase(2)] public void TestBeatDivisor(int divisor) @@ -222,6 +232,8 @@ namespace osu.Game.Tests.Editing { public new EditorBeatmap EditorBeatmap => base.EditorBeatmap; + public new Bindable DistanceSpacingMultiplier => base.DistanceSpacingMultiplier; + public TestHitObjectComposer() : base(new OsuRuleset()) { From dacca73838049da362da4f7628c5e8948fbe8322 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 06:46:34 +0300 Subject: [PATCH 21/27] Set default value of `DistanceSpacing` to 1 --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index f90208d0c0..1a9703f478 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -109,7 +109,7 @@ namespace osu.Game.Beatmaps public bool SamplesMatchPlaybackRate { get; set; } = true; - public double DistanceSpacing { get; set; } + public double DistanceSpacing { get; set; } = 1.0; public int BeatDivisor { get; set; } From 2e8372fe906996996553d275f333358b3699c9b3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 06:52:42 +0300 Subject: [PATCH 22/27] Minor cleanup Just from reading diff. --- .../Editor/TestSceneSliderSnapping.cs | 3 +-- .../Visual/Editing/TestSceneHitObjectComposer.cs | 7 +++---- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 +--- .../Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 4833266dca..6b9a0ff531 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -3,7 +3,6 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Input.Events; using osu.Framework.Testing; using osu.Framework.Utils; @@ -63,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor })); AddStep("set beat divisor to 1/1", () => { - var beatDivisor = Editor.Dependencies.Get(); + var beatDivisor = (BindableBeatDivisor)Editor.Dependencies.Get(typeof(BindableBeatDivisor)); beatDivisor.Value = 1; }); } diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 7039d7d8a4..ae1b691767 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; @@ -91,15 +90,15 @@ namespace osu.Game.Tests.Visual.Editing [Test] public void TestDistanceSpacingHotkeys() { - float originalSpacing = 0; + double originalSpacing = 0; - AddStep("retrieve original spacing", () => originalSpacing = (float)editorBeatmap.BeatmapInfo.DistanceSpacing); + AddStep("retrieve original spacing", () => originalSpacing = editorBeatmap.BeatmapInfo.DistanceSpacing); AddStep("hold ctrl", () => InputManager.PressKey(Key.LControl)); AddStep("hold alt", () => InputManager.PressKey(Key.LAlt)); AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); - AddAssert("distance spacing increased by 0.5", () => Precision.AlmostEquals(editorBeatmap.BeatmapInfo.DistanceSpacing, originalSpacing + 0.5f)); + AddAssert("distance spacing increased by 0.5", () => editorBeatmap.BeatmapInfo.DistanceSpacing == originalSpacing + 0.5); AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); AddStep("release ctrl", () => InputManager.ReleaseKey(Key.LControl)); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 9fc332d726..a235a5bc60 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -117,8 +117,6 @@ namespace osu.Game.Rulesets.Edit }, new LeftToolboxFlow { - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, Children = new Drawable[] { new EditorToolboxGroup("toolbox (1-9)") @@ -134,7 +132,7 @@ namespace osu.Game.Rulesets.Edit Direction = FillDirection.Vertical, Spacing = new Vector2(0, 5), }, - }, + } } }, }; diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 9dd6cec8ce..4f348567b1 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -84,7 +84,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.LoadComplete(); - beatDivisor.BindValueChanged(_ => updateSpacing(), true); + beatDivisor.BindValueChanged(_ => updateSpacing()); distanceSpacingMultiplier = SnapProvider.DistanceSpacingMultiplier.GetBoundCopy(); distanceSpacingMultiplier.BindValueChanged(_ => updateSpacing(), true); From 7aaa88cac2be239dcc778a1082585f8e8d5a7e55 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 10:24:36 +0300 Subject: [PATCH 23/27] Convert data type of `DistanceSpacing` to float --- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 2 +- .../TestSceneHitObjectComposerDistanceSnapping.cs | 2 +- .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- .../UserInterface/TestSceneExpandingContainer.cs | 4 ++-- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- osu.Game/Beatmaps/EFBeatmapInfo.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- .../Settings/Sections/Gameplay/InputSettings.cs | 2 +- osu.Game/Overlays/Settings/Sections/SizeSlider.cs | 7 ++----- .../Sections/UserInterface/GeneralSettings.cs | 2 +- .../Rulesets/Edit/DistancedHitObjectComposer.cs | 14 +++++++------- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 2 +- .../Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 13 files changed, 21 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index 2ba30c5f74..4cccddddf3 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -187,7 +187,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => (float)beat_length; diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index e2ff45c431..ffaf3ec41d 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -232,7 +232,7 @@ namespace osu.Game.Tests.Editing { public new EditorBeatmap EditorBeatmap => base.EditorBeatmap; - public new Bindable DistanceSpacingMultiplier => base.DistanceSpacingMultiplier; + public new Bindable DistanceSpacingMultiplier => base.DistanceSpacingMultiplier; public TestHitObjectComposer() : base(new OsuRuleset()) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index b9cfa84a5d..20bf9b3fa0 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -167,7 +167,7 @@ namespace osu.Game.Tests.Visual.Editing public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => 10; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs index 288c0cb140..f4920b4412 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface private TestExpandingContainer container; private SettingsToolboxGroup toolboxGroup; - private ExpandableSlider> slider1; + private ExpandableSlider slider1; private ExpandableSlider slider2; [SetUp] @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.UserInterface Width = 1, Children = new Drawable[] { - slider1 = new ExpandableSlider> + slider1 = new ExpandableSlider { Current = new BindableFloat { diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 1a9703f478..1b364247a8 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -109,7 +109,7 @@ namespace osu.Game.Beatmaps public bool SamplesMatchPlaybackRate { get; set; } = true; - public double DistanceSpacing { get; set; } = 1.0; + public float DistanceSpacing { get; set; } = 1.0f; public int BeatDivisor { get; set; } diff --git a/osu.Game/Beatmaps/EFBeatmapInfo.cs b/osu.Game/Beatmaps/EFBeatmapInfo.cs index 740adfd1c7..67c4dbe788 100644 --- a/osu.Game/Beatmaps/EFBeatmapInfo.cs +++ b/osu.Game/Beatmaps/EFBeatmapInfo.cs @@ -107,7 +107,7 @@ namespace osu.Game.Beatmaps [NotMapped] public int[] Bookmarks { get; set; } = Array.Empty(); - public double DistanceSpacing { get; set; } + public float DistanceSpacing { get; set; } public int BeatDivisor { get; set; } public int GridSize { get; set; } public double TimelineZoom { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 79d8bd3bb3..0ba7a07010 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -240,7 +240,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"DistanceSpacing": - beatmap.BeatmapInfo.DistanceSpacing = Math.Max(0, Parsing.ParseDouble(pair.Value)); + beatmap.BeatmapInfo.DistanceSpacing = Math.Max(0, Parsing.ParseFloat(pair.Value)); break; case @"BeatDivisor": diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs index 83ea655601..962572ca6e 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Children = new Drawable[] { - new SettingsSlider> + new SettingsSlider { LabelText = SkinSettingsStrings.GameplayCursorSize, Current = config.GetBindable(OsuSetting.GameplayCursorSize), diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index c8a46162af..8aeb440be1 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.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. -using System; -using System.Globalization; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; @@ -11,9 +9,8 @@ namespace osu.Game.Overlays.Settings.Sections /// /// A slider intended to show a "size" multiplier number, where 1x is 1.0. /// - public class SizeSlider : OsuSliderBar - where T : struct, IEquatable, IComparable, IConvertible, IFormattable + internal class SizeSlider : OsuSliderBar { - public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo); + public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x"); } } diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index 0e3b822c82..6e1558f7d7 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface LabelText = UserInterfaceStrings.CursorRotation, Current = config.GetBindable(OsuSetting.CursorRotation) }, - new SettingsSlider> + new SettingsSlider { LabelText = UserInterfaceStrings.MenuCursorSize, Current = config.GetBindable(OsuSetting.MenuCursorSize), diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index d0c9babf24..ce31318fb8 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -21,18 +21,18 @@ namespace osu.Game.Rulesets.Edit public abstract class DistancedHitObjectComposer : HitObjectComposer, IDistanceSnapProvider where TObject : HitObject { - protected Bindable DistanceSpacingMultiplier { get; } = new BindableDouble(1.0) + protected Bindable DistanceSpacingMultiplier { get; } = new BindableFloat(1.0f) { - MinValue = 0.1, - MaxValue = 6.0, - Precision = 0.01, + MinValue = 0.1f, + MaxValue = 6.0f, + Precision = 0.01f, }; - IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; + IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } - private ExpandableSlider> distanceSpacingSlider; + private ExpandableSlider distanceSpacingSlider; private bool distanceSpacingScrollActive; protected DistancedHitObjectComposer(Ruleset ruleset) @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Edit Origin = Anchor.TopRight, Child = new EditorToolboxGroup("snapping") { - Child = distanceSpacingSlider = new ExpandableSlider> + Child = distanceSpacingSlider = new ExpandableSlider { Current = { BindTarget = DistanceSpacingMultiplier }, KeyboardStep = 0.1f, diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index c6e866561e..0eb572d22a 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Edit /// The spacing multiplier applied to beat snap distances. /// /// - IBindable DistanceSpacingMultiplier { get; } + IBindable DistanceSpacingMultiplier { get; } /// /// Retrieves the distance between two points within a timing point that are one beat length apart. diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 4f348567b1..cd56beda47 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private BindableBeatDivisor beatDivisor { get; set; } - private IBindable distanceSpacingMultiplier; + private IBindable distanceSpacingMultiplier; private readonly LayoutValue gridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); private readonly double? endTime; From abb88b090702a9330401ab4c348b725b379a2d25 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 10:54:38 +0300 Subject: [PATCH 24/27] Move distance spacing application to `DistanceSnapGrid` --- .../Editor/TestSceneObjectObjectSnap.cs | 5 +---- .../Editor/TestSceneSliderSnapping.cs | 3 +-- .../TestSceneHitObjectComposerDistanceSnapping.cs | 10 ---------- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- .../Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index 21ba1e647d..7bdf131e0d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -19,10 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { private OsuPlayfield playfield; - protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false) - { - BeatmapInfo = { DistanceSpacing = 1 } - }; + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false); public override void SetUpSteps() { diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index 6b9a0ff531..b43b2b1461 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -35,8 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor controlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); return new TestBeatmap(ruleset, false) { - ControlPointInfo = controlPointInfo, - BeatmapInfo = { DistanceSpacing = 1 }, + ControlPointInfo = controlPointInfo }; } diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index ffaf3ec41d..2c2c06ae0c 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -62,7 +62,6 @@ namespace osu.Game.Tests.Editing BeatDivisor.Value = 1; composer.EditorBeatmap.Difficulty.SliderMultiplier = 1; - composer.EditorBeatmap.BeatmapInfo.DistanceSpacing = 1; composer.EditorBeatmap.ControlPointInfo.Clear(); composer.EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); }); @@ -89,15 +88,6 @@ namespace osu.Game.Tests.Editing }); } - [TestCase(1)] - [TestCase(2)] - public void TestDistanceSpacingMultiplier(float multiplier) - { - AddStep($"set distance spacing = {multiplier}", () => composer.DistanceSpacingMultiplier.Value = multiplier); - - assertSnapDistance(100 * multiplier); - } - [TestCase(1)] [TestCase(2)] public void TestBeatDivisor(int divisor) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index ce31318fb8..1e1fbb4edf 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject) { - return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * referenceObject.DifficultyControlPoint.SliderVelocity * DistanceSpacingMultiplier.Value / BeatSnapProvider.BeatDivisor); + return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * referenceObject.DifficultyControlPoint.SliderVelocity / BeatSnapProvider.BeatDivisor); } public virtual float DurationToDistance(HitObject referenceObject, double duration) diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index cd56beda47..13c3b713b1 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updateSpacing() { - DistanceSpacing = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject); + DistanceSpacing = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject) * distanceSpacingMultiplier.Value; if (endTime == null) MaxIntervals = int.MaxValue; From b6d2ca7709b0b8a32f179c0c258852217372b520 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 28 Apr 2022 10:57:14 +0300 Subject: [PATCH 25/27] Clarify TODO comment --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index a90b0d3e89..9ff6d10a49 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Edit [BackgroundDependencyLoader] private void load() { - // todo: enable distance spacing once catch supports it. + // todo: enable distance spacing once catch supports applying it to its existing distance snap grid implementation. RightSideToolboxContainer.Alpha = 0; DistanceSpacingMultiplier.Disabled = true; From fef94d49f4a57b1a1ac7bfd4fa5ef87278e2f049 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 29 Apr 2022 08:02:07 +0300 Subject: [PATCH 26/27] Revert "Convert data type of `DistanceSpacing` to float" This reverts commit 7aaa88cac2be239dcc778a1082585f8e8d5a7e55. --- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 2 +- .../TestSceneHitObjectComposerDistanceSnapping.cs | 2 +- .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- .../UserInterface/TestSceneExpandingContainer.cs | 4 ++-- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- osu.Game/Beatmaps/EFBeatmapInfo.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- .../Settings/Sections/Gameplay/InputSettings.cs | 2 +- osu.Game/Overlays/Settings/Sections/SizeSlider.cs | 7 +++++-- .../Sections/UserInterface/GeneralSettings.cs | 2 +- .../Rulesets/Edit/DistancedHitObjectComposer.cs | 14 +++++++------- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 2 +- .../Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 13 files changed, 24 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index 4cccddddf3..2ba30c5f74 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -187,7 +187,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => (float)beat_length; diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 2c2c06ae0c..a2ee97210a 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -222,7 +222,7 @@ namespace osu.Game.Tests.Editing { public new EditorBeatmap EditorBeatmap => base.EditorBeatmap; - public new Bindable DistanceSpacingMultiplier => base.DistanceSpacingMultiplier; + public new Bindable DistanceSpacingMultiplier => base.DistanceSpacingMultiplier; public TestHitObjectComposer() : base(new OsuRuleset()) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 20bf9b3fa0..b9cfa84a5d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -167,7 +167,7 @@ namespace osu.Game.Tests.Visual.Editing public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0); - public IBindable DistanceSpacingMultiplier { get; } = new BindableFloat(1); + public IBindable DistanceSpacingMultiplier { get; } = new BindableDouble(1); public float GetBeatSnapDistanceAt(HitObject referenceObject) => 10; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs index f4920b4412..288c0cb140 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface private TestExpandingContainer container; private SettingsToolboxGroup toolboxGroup; - private ExpandableSlider slider1; + private ExpandableSlider> slider1; private ExpandableSlider slider2; [SetUp] @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.UserInterface Width = 1, Children = new Drawable[] { - slider1 = new ExpandableSlider + slider1 = new ExpandableSlider> { Current = new BindableFloat { diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 1b364247a8..1a9703f478 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -109,7 +109,7 @@ namespace osu.Game.Beatmaps public bool SamplesMatchPlaybackRate { get; set; } = true; - public float DistanceSpacing { get; set; } = 1.0f; + public double DistanceSpacing { get; set; } = 1.0; public int BeatDivisor { get; set; } diff --git a/osu.Game/Beatmaps/EFBeatmapInfo.cs b/osu.Game/Beatmaps/EFBeatmapInfo.cs index 67c4dbe788..740adfd1c7 100644 --- a/osu.Game/Beatmaps/EFBeatmapInfo.cs +++ b/osu.Game/Beatmaps/EFBeatmapInfo.cs @@ -107,7 +107,7 @@ namespace osu.Game.Beatmaps [NotMapped] public int[] Bookmarks { get; set; } = Array.Empty(); - public float DistanceSpacing { get; set; } + public double DistanceSpacing { get; set; } public int BeatDivisor { get; set; } public int GridSize { get; set; } public double TimelineZoom { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 0ba7a07010..79d8bd3bb3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -240,7 +240,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"DistanceSpacing": - beatmap.BeatmapInfo.DistanceSpacing = Math.Max(0, Parsing.ParseFloat(pair.Value)); + beatmap.BeatmapInfo.DistanceSpacing = Math.Max(0, Parsing.ParseDouble(pair.Value)); break; case @"BeatDivisor": diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs index 962572ca6e..83ea655601 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Children = new Drawable[] { - new SettingsSlider + new SettingsSlider> { LabelText = SkinSettingsStrings.GameplayCursorSize, Current = config.GetBindable(OsuSetting.GameplayCursorSize), diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index 8aeb440be1..c8a46162af 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Globalization; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; @@ -9,8 +11,9 @@ namespace osu.Game.Overlays.Settings.Sections /// /// A slider intended to show a "size" multiplier number, where 1x is 1.0. /// - internal class SizeSlider : OsuSliderBar + public class SizeSlider : OsuSliderBar + where T : struct, IEquatable, IComparable, IConvertible, IFormattable { - public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x"); + public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo); } } diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index 6e1558f7d7..0e3b822c82 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface LabelText = UserInterfaceStrings.CursorRotation, Current = config.GetBindable(OsuSetting.CursorRotation) }, - new SettingsSlider + new SettingsSlider> { LabelText = UserInterfaceStrings.MenuCursorSize, Current = config.GetBindable(OsuSetting.MenuCursorSize), diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 1e1fbb4edf..0505f9ab0e 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -21,18 +21,18 @@ namespace osu.Game.Rulesets.Edit public abstract class DistancedHitObjectComposer : HitObjectComposer, IDistanceSnapProvider where TObject : HitObject { - protected Bindable DistanceSpacingMultiplier { get; } = new BindableFloat(1.0f) + protected Bindable DistanceSpacingMultiplier { get; } = new BindableDouble(1.0) { - MinValue = 0.1f, - MaxValue = 6.0f, - Precision = 0.01f, + MinValue = 0.1, + MaxValue = 6.0, + Precision = 0.01, }; - IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; + IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } - private ExpandableSlider distanceSpacingSlider; + private ExpandableSlider> distanceSpacingSlider; private bool distanceSpacingScrollActive; protected DistancedHitObjectComposer(Ruleset ruleset) @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Edit Origin = Anchor.TopRight, Child = new EditorToolboxGroup("snapping") { - Child = distanceSpacingSlider = new ExpandableSlider + Child = distanceSpacingSlider = new ExpandableSlider> { Current = { BindTarget = DistanceSpacingMultiplier }, KeyboardStep = 0.1f, diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index 0eb572d22a..c6e866561e 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Edit /// The spacing multiplier applied to beat snap distances. /// /// - IBindable DistanceSpacingMultiplier { get; } + IBindable DistanceSpacingMultiplier { get; } /// /// Retrieves the distance between two points within a timing point that are one beat length apart. diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 13c3b713b1..2500bb1f60 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit.Compose.Components [Resolved] private BindableBeatDivisor beatDivisor { get; set; } - private IBindable distanceSpacingMultiplier; + private IBindable distanceSpacingMultiplier; private readonly LayoutValue gridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); private readonly double? endTime; From 173a6188eb0d46db4a762e81213f1d377127140e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 29 Apr 2022 08:41:37 +0300 Subject: [PATCH 27/27] Add back `float` cast to distance spacing computation --- osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 2500bb1f60..5568c15514 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updateSpacing() { - DistanceSpacing = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject) * distanceSpacingMultiplier.Value; + DistanceSpacing = (float)(SnapProvider.GetBeatSnapDistanceAt(ReferenceObject) * distanceSpacingMultiplier.Value); if (endTime == null) MaxIntervals = int.MaxValue;