2021-07-08 14:53:49 +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.Framework.Graphics.Containers ;
using osu.Framework.Graphics.UserInterface ;
using osu.Game.Beatmaps ;
using osu.Game.Overlays.Settings ;
namespace osu.Game.Rulesets.Mods
{
public class DifficultyAdjustSettingsControl : SettingsItem < float? >
{
[Resolved]
private IBindable < WorkingBeatmap > beatmap { get ; set ; }
2021-07-08 16:39:59 +08:00
/// <summary>
/// Used to track the display value on the setting slider.
/// </summary>
2021-07-09 12:50:07 +08:00
/// <remarks>
/// When the mod is overriding a default, this will match the value of <see cref="Current"/>.
2021-07-09 12:58:44 +08:00
/// When there is no override (ie. <see cref="Current"/> is null), this value will match the beatmap provided default via <see cref="updateCurrentFromSlider"/>.
2021-07-09 12:50:07 +08:00
/// </remarks>
private readonly BindableNumber < float > sliderDisplayCurrent = new BindableNumber < float > ( ) ;
2021-07-08 14:53:49 +08:00
2021-07-09 12:50:07 +08:00
protected override Drawable CreateControl ( ) = > new SliderControl ( sliderDisplayCurrent ) ;
2021-07-08 14:53:49 +08:00
2021-07-09 12:58:44 +08:00
/// <summary>
/// Guards against beatmap values displayed on slider bars being transferred to user override.
/// </summary>
2021-07-08 14:53:49 +08:00
private bool isInternalChange ;
2021-07-08 15:40:32 +08:00
private DifficultyBindable difficultyBindable ;
public override Bindable < float? > Current
{
get = > base . Current ;
set
{
2021-07-09 12:50:07 +08:00
// Intercept and extract the internal number bindable from DifficultyBindable.
// This will provide bounds and precision specifications for the slider bar.
2021-07-11 21:12:46 +08:00
difficultyBindable = ( ( DifficultyBindable ) value ) . GetBoundCopy ( ) ;
2021-07-09 12:50:07 +08:00
sliderDisplayCurrent . BindTo ( difficultyBindable . CurrentNumber ) ;
2021-07-08 16:39:59 +08:00
2021-07-11 21:12:46 +08:00
base . Current = difficultyBindable ;
2021-07-08 15:40:32 +08:00
}
}
2021-07-08 14:53:49 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2021-07-09 12:58:44 +08:00
Current . BindValueChanged ( current = > updateCurrentFromSlider ( ) ) ;
beatmap . BindValueChanged ( b = > updateCurrentFromSlider ( ) , true ) ;
2021-07-08 14:53:49 +08:00
2021-07-09 12:50:07 +08:00
sliderDisplayCurrent . BindValueChanged ( number = >
2021-07-08 14:53:49 +08:00
{
2021-07-09 12:50:07 +08:00
// this handles the transfer of the slider value to the main bindable.
// as such, should be skipped if the slider is being updated via updateFromDifficulty().
2021-07-08 14:53:49 +08:00
if ( ! isInternalChange )
Current . Value = number . NewValue ;
} ) ;
}
2021-07-09 12:58:44 +08:00
private void updateCurrentFromSlider ( )
2021-07-08 14:53:49 +08:00
{
2021-07-09 12:58:44 +08:00
if ( Current . Value ! = null )
{
// a user override has been added or updated.
sliderDisplayCurrent . Value = Current . Value . Value ;
return ;
}
2021-07-08 14:53:49 +08:00
var difficulty = beatmap . Value . BeatmapInfo . BaseDifficulty ;
if ( difficulty = = null )
return ;
2021-07-09 12:58:44 +08:00
// generally should always be implemented, else the slider will have a zero default.
if ( difficultyBindable . ReadCurrentFromDifficulty = = null )
return ;
isInternalChange = true ;
sliderDisplayCurrent . Value = difficultyBindable . ReadCurrentFromDifficulty ( difficulty ) ;
isInternalChange = false ;
2021-07-08 14:53:49 +08:00
}
2021-07-08 19:37:38 +08:00
private class SliderControl : CompositeDrawable , IHasCurrentValue < float? >
2021-07-08 14:53:49 +08:00
{
2021-07-09 12:50:07 +08:00
// This is required as SettingsItem relies heavily on this bindable for internal use.
// The actual update flow is done via the bindable provided in the constructor.
2021-08-16 17:47:56 +08:00
private readonly BindableWithCurrent < float? > current = new BindableWithCurrent < float? > ( ) ;
public Bindable < float? > Current
{
get = > current . Current ;
set = > current . Current = value ;
}
2021-07-08 14:53:49 +08:00
2021-07-08 19:37:38 +08:00
public SliderControl ( BindableNumber < float > currentNumber )
2021-07-08 14:53:49 +08:00
{
InternalChildren = new Drawable [ ]
{
new SettingsSlider < float >
{
ShowsDefaultIndicator = false ,
Current = currentNumber ,
}
} ;
AutoSizeAxes = Axes . Y ;
RelativeSizeAxes = Axes . X ;
}
}
}
}