1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 03:47:26 +08:00
osu-lazer/osu.Game/Screens/Edit/Timing/TimingSection.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

118 lines
3.7 KiB
C#
Raw Normal View History

2019-10-28 11:42:17 +08:00
// 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.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Beatmaps.ControlPoints;
2020-09-07 16:39:13 +08:00
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Screens.Edit.Timing
{
internal class TimingSection : Section<TimingControlPoint>
{
private LabelledTimeSignature timeSignature;
2020-09-07 16:39:13 +08:00
private BPMTextBox bpmTextEntry;
[BackgroundDependencyLoader]
private void load()
{
Flow.AddRange(new Drawable[]
{
2022-05-20 13:34:33 +08:00
new TapTimingControl(),
bpmTextEntry = new BPMTextBox(),
timeSignature = new LabelledTimeSignature
{
Label = "Time Signature"
}
});
}
protected override void LoadComplete()
{
base.LoadComplete();
bpmTextEntry.Current.BindValueChanged(_ => saveChanges());
timeSignature.Current.BindValueChanged(_ => saveChanges());
void saveChanges()
{
if (!isRebinding) ChangeHandler?.SaveState();
}
}
private bool isRebinding;
protected override void OnControlPointChanged(ValueChangedEvent<TimingControlPoint> point)
{
if (point.NewValue != null)
{
isRebinding = true;
2020-10-02 16:55:47 +08:00
bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable;
timeSignature.Current = point.NewValue.TimeSignatureBindable;
isRebinding = false;
}
}
protected override TimingControlPoint CreatePoint()
{
var reference = Beatmap.ControlPointInfo.TimingPointAt(SelectedGroup.Value.Time);
return new TimingControlPoint
{
BeatLength = reference.BeatLength,
TimeSignature = reference.TimeSignature
};
}
2020-09-07 16:39:13 +08:00
private class BPMTextBox : LabelledTextBox
{
private readonly BindableNumber<double> beatLengthBindable = new TimingControlPoint().BeatLengthBindable;
2020-09-07 16:39:13 +08:00
public BPMTextBox()
{
Label = "BPM";
2020-09-07 16:39:13 +08:00
OnCommit += (val, isNew) =>
{
if (!isNew) return;
try
2020-09-07 16:39:13 +08:00
{
if (double.TryParse(Current.Value, out double doubleVal) && doubleVal > 0)
2020-09-07 16:39:13 +08:00
beatLengthBindable.Value = beatLengthToBpm(doubleVal);
}
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();
2020-09-07 16:39:13 +08:00
};
beatLengthBindable.BindValueChanged(val =>
{
Current.Value = beatLengthToBpm(val.NewValue).ToString("N2");
}, true);
2020-09-07 16:39:13 +08:00
}
public Bindable<double> Bindable
{
get => beatLengthBindable;
set
{
// incoming will be beat length, not bpm
beatLengthBindable.UnbindBindings();
beatLengthBindable.BindTo(value);
}
}
}
private static double beatLengthToBpm(double beatLength) => 60000 / beatLength;
}
}