diff --git a/osu.Android.props b/osu.Android.props
index afc5d4ec52..78ceaa8616 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs
index aee5241e35..a1b5ac38ea 100644
--- a/osu.Game.Tournament/Components/DateTextBox.cs
+++ b/osu.Game.Tournament/Components/DateTextBox.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Tournament.Components
{
base.Bindable = new Bindable();
- ((OsuTextBox)Control).OnCommit = (sender, newText) =>
+ ((OsuTextBox)Control).OnCommit += (sender, newText) =>
{
try
{
diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs
index f8810c778f..8b0caddbc6 100644
--- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs
+++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs
@@ -59,12 +59,13 @@ namespace osu.Game.Online.Chat
RelativeSizeAxes = Axes.X,
Height = textbox_height,
PlaceholderText = "type your message",
- OnCommit = postMessage,
ReleaseFocusOnCommit = false,
HoldFocus = true,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
});
+
+ textbox.OnCommit += postMessage;
}
Channel.BindValueChanged(channelChanged);
diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs
index c53eccf78b..8bc7e21047 100644
--- a/osu.Game/Overlays/ChatOverlay.cs
+++ b/osu.Game/Overlays/ChatOverlay.cs
@@ -146,7 +146,6 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both,
Height = 1,
PlaceholderText = "type your message",
- OnCommit = postMessage,
ReleaseFocusOnCommit = false,
HoldFocus = true,
}
@@ -186,6 +185,8 @@ namespace osu.Game.Overlays
},
};
+ textbox.OnCommit += postMessage;
+
ChannelTabControl.Current.ValueChanged += current => channelManager.CurrentChannel.Value = current.NewValue;
ChannelTabControl.ChannelSelectorActive.ValueChanged += active => ChannelSelectionOverlay.State.Value = active.NewValue ? Visibility.Visible : Visibility.Hidden;
ChannelSelectionOverlay.State.ValueChanged += state =>
diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs
index 050e687dfb..b8d04eab4e 100644
--- a/osu.Game/Overlays/Music/PlaylistOverlay.cs
+++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs
@@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music
},
};
- filter.Search.OnCommit = (sender, newText) =>
+ filter.Search.OnCommit += (sender, newText) =>
{
BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
index 34e5da4ef4..f96e204f62 100644
--- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
@@ -236,7 +236,6 @@ namespace osu.Game.Overlays.Settings.Sections.General
PlaceholderText = "password",
RelativeSizeAxes = Axes.X,
TabbableContentContainer = this,
- OnCommit = (sender, newText) => performLogin()
},
new SettingsCheckbox
{
@@ -276,6 +275,8 @@ namespace osu.Game.Overlays.Settings.Sections.General
}
}
};
+
+ password.OnCommit += (sender, newText) => performLogin();
}
public override bool AcceptsFocus => true;
diff --git a/osu.Game/Screens/Edit/Timing/DifficultySection.cs b/osu.Game/Screens/Edit/Timing/DifficultySection.cs
index 58a7f97e5f..78766d9777 100644
--- a/osu.Game/Screens/Edit/Timing/DifficultySection.cs
+++ b/osu.Game/Screens/Edit/Timing/DifficultySection.cs
@@ -2,27 +2,23 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Graphics;
using osu.Framework.Bindables;
using osu.Game.Beatmaps.ControlPoints;
-using osu.Game.Overlays.Settings;
namespace osu.Game.Screens.Edit.Timing
{
internal class DifficultySection : Section
{
- private SettingsSlider multiplier;
+ private SliderWithTextBoxInput multiplierSlider;
[BackgroundDependencyLoader]
private void load()
{
Flow.AddRange(new[]
{
- multiplier = new SettingsSlider
+ multiplierSlider = new SliderWithTextBoxInput("Speed Multiplier")
{
- LabelText = "Speed Multiplier",
- Bindable = new DifficultyControlPoint().SpeedMultiplierBindable,
- RelativeSizeAxes = Axes.X,
+ Current = new DifficultyControlPoint().SpeedMultiplierBindable
}
});
}
@@ -31,7 +27,7 @@ namespace osu.Game.Screens.Edit.Timing
{
if (point.NewValue != null)
{
- multiplier.Bindable = point.NewValue.SpeedMultiplierBindable;
+ multiplierSlider.Current = point.NewValue.SpeedMultiplierBindable;
}
}
diff --git a/osu.Game/Screens/Edit/Timing/SampleSection.cs b/osu.Game/Screens/Edit/Timing/SampleSection.cs
index 4665c77991..de986e28ca 100644
--- a/osu.Game/Screens/Edit/Timing/SampleSection.cs
+++ b/osu.Game/Screens/Edit/Timing/SampleSection.cs
@@ -2,18 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Graphics;
using osu.Framework.Bindables;
+using osu.Framework.Graphics;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.UserInterfaceV2;
-using osu.Game.Overlays.Settings;
namespace osu.Game.Screens.Edit.Timing
{
internal class SampleSection : Section
{
private LabelledTextBox bank;
- private SettingsSlider volume;
+ private SliderWithTextBoxInput volume;
[BackgroundDependencyLoader]
private void load()
@@ -24,10 +23,9 @@ namespace osu.Game.Screens.Edit.Timing
{
Label = "Bank Name",
},
- volume = new SettingsSlider
+ volume = new SliderWithTextBoxInput("Volume")
{
- Bindable = new SampleControlPoint().SampleVolumeBindable,
- LabelText = "Volume",
+ Current = new SampleControlPoint().SampleVolumeBindable,
}
});
}
@@ -37,7 +35,7 @@ namespace osu.Game.Screens.Edit.Timing
if (point.NewValue != null)
{
bank.Current = point.NewValue.SampleBankBindable;
- volume.Bindable = point.NewValue.SampleVolumeBindable;
+ volume.Current = point.NewValue.SampleVolumeBindable;
}
}
diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs
new file mode 100644
index 0000000000..14023b0c35
--- /dev/null
+++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs
@@ -0,0 +1,77 @@
+// 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.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Graphics.UserInterfaceV2;
+using osu.Game.Overlays.Settings;
+
+namespace osu.Game.Screens.Edit.Timing
+{
+ internal class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue
+ where T : struct, IEquatable, IComparable, IConvertible
+ {
+ private readonly SettingsSlider slider;
+
+ public SliderWithTextBoxInput(string labelText)
+ {
+ LabelledTextBox textbox;
+
+ RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
+
+ InternalChildren = new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ textbox = new LabelledTextBox
+ {
+ Label = labelText,
+ },
+ slider = new SettingsSlider
+ {
+ RelativeSizeAxes = Axes.X,
+ }
+ }
+ },
+ };
+
+ textbox.OnCommit += (t, isNew) =>
+ {
+ if (!isNew) return;
+
+ try
+ {
+ slider.Bindable.Parse(t.Text);
+ }
+ catch
+ {
+ // TriggerChange below will restore the previous text value on failure.
+ }
+
+ // This is run regardless of parsing success as the parsed number may not actually trigger a change
+ // due to bindable clamping. Even in such a case we want to update the textbox to a sane visual state.
+ Current.TriggerChange();
+ };
+
+ Current.BindValueChanged(val =>
+ {
+ textbox.Text = val.NewValue.ToString();
+ }, true);
+ }
+
+ public Bindable Current
+ {
+ get => slider.Bindable;
+ set => slider.Bindable = value;
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs
index cc79dd2acc..0202441537 100644
--- a/osu.Game/Screens/Edit/Timing/TimingSection.cs
+++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs
@@ -65,18 +65,19 @@ namespace osu.Game.Screens.Edit.Timing
{
if (!isNew) return;
- if (double.TryParse(Current.Value, out double doubleVal))
+ try
{
- try
- {
+ if (double.TryParse(Current.Value, out double doubleVal) && doubleVal > 0)
beatLengthBindable.Value = beatLengthToBpm(doubleVal);
- }
- catch
- {
- // will restore the previous text value on failure.
- beatLengthBindable.TriggerChange();
- }
}
+ catch
+ {
+ // TriggerChange below will restore the previous text value on failure.
+ }
+
+ // This is run regardless of parsing success as the parsed number may not actually trigger a change
+ // due to bindable clamping. Even in such a case we want to update the textbox to a sane visual state.
+ beatLengthBindable.TriggerChange();
};
beatLengthBindable.BindValueChanged(val =>
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 5fa1685d9b..3a839ac1a4 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -24,7 +24,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 60708a39e2..48c91f0d53 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -70,7 +70,7 @@
-
+
@@ -80,7 +80,7 @@
-
+