From 6091714f158ff4675612d43de3bf1be99b1910f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 17:34:30 +0900 Subject: [PATCH 1/5] Limit BPM entry via slider to a sane range --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 906644ce14..8e6ea90797 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.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.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -12,7 +13,7 @@ namespace osu.Game.Screens.Edit.Timing { internal class TimingSection : Section { - private SettingsSlider bpm; + private SettingsSlider bpmSlider; private SettingsEnumDropdown timeSignature; [BackgroundDependencyLoader] @@ -20,7 +21,7 @@ namespace osu.Game.Screens.Edit.Timing { Flow.AddRange(new Drawable[] { - bpm = new BPMSlider + bpmSlider = new BPMSlider { Bindable = new TimingControlPoint().BeatLengthBindable, LabelText = "BPM", @@ -36,7 +37,7 @@ namespace osu.Game.Screens.Edit.Timing { if (point.NewValue != null) { - bpm.Bindable = point.NewValue.BeatLengthBindable; + bpmSlider.Bindable = point.NewValue.BeatLengthBindable; timeSignature.Bindable = point.NewValue.TimeSignatureBindable; } } @@ -54,6 +55,9 @@ namespace osu.Game.Screens.Edit.Timing private class BPMSlider : SettingsSlider { + private const double sane_minimum = 60; + private const double sane_maximum = 200; + private readonly BindableDouble beatLengthBindable = new BindableDouble(); private BindableDouble bpmBindable; @@ -63,22 +67,39 @@ namespace osu.Game.Screens.Edit.Timing get => base.Bindable; set { - // incoming will be beatlength - + // incoming will be beat length, not bpm beatLengthBindable.UnbindBindings(); beatLengthBindable.BindTo(value); - base.Bindable = bpmBindable = new BindableDouble(beatLengthToBpm(beatLengthBindable.Value)) + double initial = beatLengthToBpm(beatLengthBindable.Value); + + bpmBindable = new BindableDouble(initial) { - MinValue = beatLengthToBpm(beatLengthBindable.MaxValue), - MaxValue = beatLengthToBpm(beatLengthBindable.MinValue), Default = beatLengthToBpm(beatLengthBindable.Default), }; - bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); + updateCurrent(initial); + + bpmBindable.BindValueChanged(bpm => + { + updateCurrent(bpm.NewValue); + beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue); + }); + + base.Bindable = bpmBindable; } } + private void updateCurrent(double newValue) + { + // we use a more sane range for the slider display unless overridden by the user. + // if a value comes in outside our range, we should expand temporarily. + bpmBindable.MinValue = Math.Min(newValue, sane_minimum); + bpmBindable.MaxValue = Math.Max(newValue, sane_maximum); + + bpmBindable.Value = newValue; + } + private double beatLengthToBpm(double beatLength) => 60000 / beatLength; } } From 86512d6e8d4ad6ba2d20c14bcc76a6fd2708f372 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 17:39:13 +0900 Subject: [PATCH 2/5] Add BPM entry textbox --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 81 ++++++++++++++----- 1 file changed, 60 insertions(+), 21 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 8e6ea90797..6fed4589ce 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Edit.Timing @@ -15,16 +16,21 @@ namespace osu.Game.Screens.Edit.Timing { private SettingsSlider bpmSlider; private SettingsEnumDropdown timeSignature; + private BPMTextBox bpmTextEntry; [BackgroundDependencyLoader] private void load() { Flow.AddRange(new Drawable[] { + bpmTextEntry = new BPMTextBox + { + Bindable = new TimingControlPoint().BeatLengthBindable, + Label = "BPM", + }, bpmSlider = new BPMSlider { Bindable = new TimingControlPoint().BeatLengthBindable, - LabelText = "BPM", }, timeSignature = new SettingsEnumDropdown { @@ -38,6 +44,7 @@ namespace osu.Game.Screens.Edit.Timing if (point.NewValue != null) { bpmSlider.Bindable = point.NewValue.BeatLengthBindable; + bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable; timeSignature.Bindable = point.NewValue.TimeSignatureBindable; } } @@ -53,14 +60,63 @@ namespace osu.Game.Screens.Edit.Timing }; } + private class BPMTextBox : LabelledTextBox + { + public BPMTextBox() + { + OnCommit += (val, isNew) => + { + if (!isNew) return; + + if (double.TryParse(Current.Value, out double doubleVal)) + { + try + { + beatLengthBindable.Value = beatLengthToBpm(doubleVal); + } + catch + { + // will restore the previous text value on failure. + beatLengthBindable.TriggerChange(); + } + } + }; + + beatLengthBindable.BindValueChanged(val => + { + Current.Value = beatLengthToBpm(val.NewValue).ToString(); + }); + } + + private readonly BindableDouble beatLengthBindable = new BindableDouble(); + + public Bindable Bindable + { + get => beatLengthBindable; + set + { + // incoming will be beat length, not bpm + beatLengthBindable.UnbindBindings(); + beatLengthBindable.BindTo(value); + } + } + } + private class BPMSlider : SettingsSlider { private const double sane_minimum = 60; private const double sane_maximum = 200; private readonly BindableDouble beatLengthBindable = new BindableDouble(); + private readonly BindableDouble bpmBindable = new BindableDouble(); - private BindableDouble bpmBindable; + public BPMSlider() + { + beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue))); + bpmBindable.BindValueChanged(bpm => bpmBindable.Default = beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); + + base.Bindable = bpmBindable; + } public override Bindable Bindable { @@ -70,23 +126,6 @@ namespace osu.Game.Screens.Edit.Timing // incoming will be beat length, not bpm beatLengthBindable.UnbindBindings(); beatLengthBindable.BindTo(value); - - double initial = beatLengthToBpm(beatLengthBindable.Value); - - bpmBindable = new BindableDouble(initial) - { - Default = beatLengthToBpm(beatLengthBindable.Default), - }; - - updateCurrent(initial); - - bpmBindable.BindValueChanged(bpm => - { - updateCurrent(bpm.NewValue); - beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue); - }); - - base.Bindable = bpmBindable; } } @@ -99,8 +138,8 @@ namespace osu.Game.Screens.Edit.Timing bpmBindable.Value = newValue; } - - private double beatLengthToBpm(double beatLength) => 60000 / beatLength; } + + private static double beatLengthToBpm(double beatLength) => 60000 / beatLength; } } From 98676af7bb3b737aeb07f8fbb8f7a821e21372d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:18:34 +0900 Subject: [PATCH 3/5] Move default declarations for readability --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 6fed4589ce..0112471522 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -23,15 +23,8 @@ namespace osu.Game.Screens.Edit.Timing { Flow.AddRange(new Drawable[] { - bpmTextEntry = new BPMTextBox - { - Bindable = new TimingControlPoint().BeatLengthBindable, - Label = "BPM", - }, - bpmSlider = new BPMSlider - { - Bindable = new TimingControlPoint().BeatLengthBindable, - }, + bpmTextEntry = new BPMTextBox(), + bpmSlider = new BPMSlider(), timeSignature = new SettingsEnumDropdown { LabelText = "Time Signature" @@ -62,8 +55,12 @@ namespace osu.Game.Screens.Edit.Timing private class BPMTextBox : LabelledTextBox { + private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; + public BPMTextBox() { + Label = "BPM"; + OnCommit += (val, isNew) => { if (!isNew) return; @@ -84,12 +81,10 @@ namespace osu.Game.Screens.Edit.Timing beatLengthBindable.BindValueChanged(val => { - Current.Value = beatLengthToBpm(val.NewValue).ToString(); - }); + Current.Value = beatLengthToBpm(val.NewValue).ToString("N2"); + }, true); } - private readonly BindableDouble beatLengthBindable = new BindableDouble(); - public Bindable Bindable { get => beatLengthBindable; @@ -107,12 +102,12 @@ namespace osu.Game.Screens.Edit.Timing private const double sane_minimum = 60; private const double sane_maximum = 200; - private readonly BindableDouble beatLengthBindable = new BindableDouble(); + private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; private readonly BindableDouble bpmBindable = new BindableDouble(); public BPMSlider() { - beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue))); + beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true); bpmBindable.BindValueChanged(bpm => bpmBindable.Default = beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); base.Bindable = bpmBindable; From 1468b9589fd7e843cc53c27dcfa6cddcb7bcf1a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 18:20:47 +0900 Subject: [PATCH 4/5] Increase max sane BPM value --- osu.Game/Screens/Edit/Timing/TimingSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 0112471522..879363ba08 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Timing private class BPMSlider : SettingsSlider { private const double sane_minimum = 60; - private const double sane_maximum = 200; + private const double sane_maximum = 240; private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; private readonly BindableDouble bpmBindable = new BindableDouble(); From 2b62579488c76a5f3bc65455085178912081e459 Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 7 Sep 2020 10:18:22 -0700 Subject: [PATCH 5/5] Lowercase one more toolbar tooltip --- osu.Game/Overlays/ChatOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index bcc2227be8..25a59e9b25 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/messaging"; public string Title => "chat"; - public string Description => "Join the real-time discussion"; + public string Description => "join the real-time discussion"; private const float textbox_height = 60; private const float channel_selection_min_height = 0.3f;