1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:17:26 +08:00

Merge pull request #23722 from peppy/beat-divisor-better-defaults

Improve usability of beat divisor control
This commit is contained in:
Bartłomiej Dach 2023-06-08 21:16:03 +02:00 committed by GitHub
commit 3597698544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 25 deletions

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -23,8 +21,8 @@ namespace osu.Game.Tests.Visual.Editing
{ {
public partial class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene public partial class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
{ {
private BeatDivisorControl beatDivisorControl; private BeatDivisorControl beatDivisorControl = null!;
private BindableBeatDivisor bindableBeatDivisor; private BindableBeatDivisor bindableBeatDivisor = null!;
private SliderBar<int> tickSliderBar => beatDivisorControl.ChildrenOfType<SliderBar<int>>().Single(); private SliderBar<int> tickSliderBar => beatDivisorControl.ChildrenOfType<SliderBar<int>>().Single();
private Triangle tickMarkerHead => tickSliderBar.ChildrenOfType<Triangle>().Single(); private Triangle tickMarkerHead => tickSliderBar.ChildrenOfType<Triangle>().Single();
@ -169,9 +167,11 @@ namespace osu.Game.Tests.Visual.Editing
switchPresets(1); switchPresets(1);
assertPreset(BeatDivisorType.Triplets); assertPreset(BeatDivisorType.Triplets);
assertBeatSnap(6);
switchPresets(1); switchPresets(1);
assertPreset(BeatDivisorType.Common); assertPreset(BeatDivisorType.Common);
assertBeatSnap(4);
switchPresets(-1); switchPresets(-1);
assertPreset(BeatDivisorType.Triplets); assertPreset(BeatDivisorType.Triplets);
@ -187,6 +187,7 @@ namespace osu.Game.Tests.Visual.Editing
setDivisorViaInput(15); setDivisorViaInput(15);
assertPreset(BeatDivisorType.Custom, 15); assertPreset(BeatDivisorType.Custom, 15);
assertBeatSnap(15);
switchBeatSnap(-1); switchBeatSnap(-1);
assertBeatSnap(5); assertBeatSnap(5);
@ -196,12 +197,14 @@ namespace osu.Game.Tests.Visual.Editing
setDivisorViaInput(5); setDivisorViaInput(5);
assertPreset(BeatDivisorType.Custom, 15); assertPreset(BeatDivisorType.Custom, 15);
assertBeatSnap(5);
switchPresets(1); switchPresets(1);
assertPreset(BeatDivisorType.Common); assertPreset(BeatDivisorType.Common);
switchPresets(-1); switchPresets(-1);
assertPreset(BeatDivisorType.Triplets); assertPreset(BeatDivisorType.Custom, 15);
assertBeatSnap(15);
} }
private void switchBeatSnap(int direction) => AddRepeatStep($"move snap {(direction > 0 ? "forward" : "backward")}", () => private void switchBeatSnap(int direction) => AddRepeatStep($"move snap {(direction > 0 ? "forward" : "backward")}", () =>
@ -225,7 +228,7 @@ namespace osu.Game.Tests.Visual.Editing
private void assertPreset(BeatDivisorType type, int? maxDivisor = null) private void assertPreset(BeatDivisorType type, int? maxDivisor = null)
{ {
AddAssert($"preset is {type}", () => bindableBeatDivisor.ValidDivisors.Value.Type == type); AddAssert($"preset is {type}", () => bindableBeatDivisor.ValidDivisors.Value.Type, () => Is.EqualTo(type));
if (type == BeatDivisorType.Custom) if (type == BeatDivisorType.Custom)
{ {
@ -243,7 +246,7 @@ namespace osu.Game.Tests.Visual.Editing
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
BeatDivisorControl.CustomDivisorPopover popover = null; BeatDivisorControl.CustomDivisorPopover? popover = null;
AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType<BeatDivisorControl.CustomDivisorPopover>().SingleOrDefault()) != null && popover.IsLoaded); AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType<BeatDivisorControl.CustomDivisorPopover>().SingleOrDefault()) != null && popover.IsLoaded);
AddStep($"set divisor to {divisor}", () => AddStep($"set divisor to {divisor}", () =>
{ {

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
#nullable disable
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -33,6 +31,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
public partial class BeatDivisorControl : CompositeDrawable, IKeyBindingHandler<GlobalAction> public partial class BeatDivisorControl : CompositeDrawable, IKeyBindingHandler<GlobalAction>
{ {
private int? lastCustomDivisor;
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
public BeatDivisorControl(BindableBeatDivisor beatDivisor) public BeatDivisorControl(BindableBeatDivisor beatDivisor)
@ -186,29 +186,46 @@ namespace osu.Game.Screens.Edit.Compose.Components
}; };
} }
protected override void LoadComplete()
{
base.LoadComplete();
beatDivisor.ValidDivisors.BindValueChanged(valid =>
{
if (valid.NewValue.Type == BeatDivisorType.Custom)
lastCustomDivisor = valid.NewValue.Presets.Last();
}, true);
}
private void cycleDivisorType(int direction) private void cycleDivisorType(int direction)
{ {
Debug.Assert(Math.Abs(direction) == 1); int totalTypes = Enum.GetValues<BeatDivisorType>().Length;
int nextDivisorType = (int)beatDivisor.ValidDivisors.Value.Type + direction; BeatDivisorType currentType = beatDivisor.ValidDivisors.Value.Type;
if (nextDivisorType > (int)BeatDivisorType.Triplets)
nextDivisorType = (int)BeatDivisorType.Common;
else if (nextDivisorType < (int)BeatDivisorType.Common)
nextDivisorType = (int)BeatDivisorType.Triplets;
switch ((BeatDivisorType)nextDivisorType) Debug.Assert(Math.Abs(direction) == 1);
cycleOnce();
if (lastCustomDivisor == null && currentType == BeatDivisorType.Custom)
cycleOnce();
switch (currentType)
{ {
case BeatDivisorType.Common: case BeatDivisorType.Common:
beatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.COMMON; beatDivisor.SetArbitraryDivisor(4);
break; break;
case BeatDivisorType.Triplets: case BeatDivisorType.Triplets:
beatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.TRIPLETS; beatDivisor.SetArbitraryDivisor(6);
break; break;
case BeatDivisorType.Custom: case BeatDivisorType.Custom:
beatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.Custom(beatDivisor.ValidDivisors.Value.Presets.Max()); Debug.Assert(lastCustomDivisor != null);
beatDivisor.SetArbitraryDivisor(lastCustomDivisor.Value);
break; break;
} }
void cycleOnce() => currentType = (BeatDivisorType)(((int)currentType + totalTypes + direction) % totalTypes);
} }
protected override bool OnKeyDown(KeyDownEvent e) protected override bool OnKeyDown(KeyDownEvent e)
@ -326,12 +343,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
base.LoadComplete(); base.LoadComplete();
BeatDivisor.BindValueChanged(_ => updateState(), true); BeatDivisor.BindValueChanged(_ => updateState(), true);
divisorTextBox.OnCommit += (_, _) => setPresets(); divisorTextBox.OnCommit += (_, _) => setPresetsFromTextBoxEntry();
Schedule(() => GetContainingInputManager().ChangeFocus(divisorTextBox)); Schedule(() => GetContainingInputManager().ChangeFocus(divisorTextBox));
} }
private void setPresets() private void setPresetsFromTextBoxEntry()
{ {
if (!int.TryParse(divisorTextBox.Text, out int divisor) || divisor < 1 || divisor > 64) if (!int.TryParse(divisorTextBox.Text, out int divisor) || divisor < 1 || divisor > 64)
{ {
@ -394,10 +411,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
private partial class TickSliderBar : SliderBar<int> private partial class TickSliderBar : SliderBar<int>
{ {
private Marker marker; private Marker marker = null!;
[Resolved] [Resolved]
private OsuColour colours { get; set; } private OsuColour colours { get; set; } = null!;
private readonly BindableBeatDivisor beatDivisor; private readonly BindableBeatDivisor beatDivisor;
@ -539,7 +556,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private partial class Marker : CompositeDrawable private partial class Marker : CompositeDrawable
{ {
[Resolved] [Resolved]
private OverlayColourProvider colourProvider { get; set; } private OverlayColourProvider colourProvider { get; set; } = null!;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()

View File

@ -82,7 +82,7 @@ namespace osu.Game.Screens.Edit
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Right = 5 }, Padding = new MarginPadding { Right = 5 },
}, },
new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } new BeatDivisorControl(this.beatDivisor) { RelativeSizeAxes = Axes.Both }
}, },
}, },
RowDimensions = new[] RowDimensions = new[]