1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 21:02:54 +08:00

Merge branch 'master' into confine-during-gameplay

# Conflicts:
#	osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs
This commit is contained in:
Shane Woolcock 2020-10-07 11:07:00 +10:30
commit ec12a21088
46 changed files with 686 additions and 417 deletions

View File

@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Mania
new SettingsEnumDropdown<ManiaScrollingDirection> new SettingsEnumDropdown<ManiaScrollingDirection>
{ {
LabelText = "Scrolling direction", LabelText = "Scrolling direction",
Bindable = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection) Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
}, },
new SettingsSlider<double, TimeSlider> new SettingsSlider<double, TimeSlider>
{ {
LabelText = "Scroll speed", LabelText = "Scroll speed",
Bindable = config.GetBindable<double>(ManiaRulesetSetting.ScrollTime), Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollTime),
KeyboardStep = 5 KeyboardStep = 5
}, },
}; };

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Origin = Anchor.Centre; Origin = Anchor.Centre;
Masking = true; Masking = true;
BorderThickness = 10; BorderThickness = 9; // roughly matches slider borders and makes stacked circles distinctly visible from each other.
BorderColour = Color4.White; BorderColour = Color4.White;
Child = new Box Child = new Box

View File

@ -49,6 +49,23 @@ namespace osu.Game.Rulesets.Osu.Skinning
{ {
OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject;
bool allowFallback = false;
// attempt lookup using priority specification
Texture baseTexture = getTextureWithFallback(string.Empty);
// if the base texture was not found without a fallback, switch on fallback mode and re-perform the lookup.
if (baseTexture == null)
{
allowFallback = true;
baseTexture = getTextureWithFallback(string.Empty);
}
// at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it.
// the flow above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist.
// expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png (potentially from the default/fall-through skin).
Texture overlayTexture = getTextureWithFallback("overlay");
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
circleSprites = new Container<Sprite> circleSprites = new Container<Sprite>
@ -60,13 +77,13 @@ namespace osu.Game.Rulesets.Osu.Skinning
{ {
hitCircleSprite = new Sprite hitCircleSprite = new Sprite
{ {
Texture = getTextureWithFallback(string.Empty), Texture = baseTexture,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
}, },
hitCircleOverlay = new Sprite hitCircleOverlay = new Sprite
{ {
Texture = getTextureWithFallback("overlay"), Texture = overlayTexture,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
} }
@ -101,8 +118,13 @@ namespace osu.Game.Rulesets.Osu.Skinning
Texture tex = null; Texture tex = null;
if (!string.IsNullOrEmpty(priorityLookup)) if (!string.IsNullOrEmpty(priorityLookup))
{
tex = skin.GetTexture($"{priorityLookup}{name}"); tex = skin.GetTexture($"{priorityLookup}{name}");
if (!allowFallback)
return tex;
}
return tex ?? skin.GetTexture($"hitcircle{name}"); return tex ?? skin.GetTexture($"hitcircle{name}");
} }
} }

View File

@ -27,17 +27,17 @@ namespace osu.Game.Rulesets.Osu.UI
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Snaking in sliders", LabelText = "Snaking in sliders",
Bindable = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders) Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Snaking out sliders", LabelText = "Snaking out sliders",
Bindable = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders) Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Cursor trail", LabelText = "Cursor trail",
Bindable = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail) Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail)
}, },
}; };
} }

View File

@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual.Editing
using (var zip = ZipArchive.Open(temp)) using (var zip = ZipArchive.Open(temp))
zip.WriteToDirectory(extractedFolder); zip.WriteToDirectory(extractedFolder);
bool success = setup.ChangeAudioTrack(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3")); bool success = setup.ChildrenOfType<ResourcesSection>().First().ChangeAudioTrack(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3"));
File.Delete(temp); File.Delete(temp);
Directory.Delete(extractedFolder, true); Directory.Delete(extractedFolder, true);

View File

@ -0,0 +1,46 @@
// 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 NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneLabelledSliderBar : OsuTestScene
{
[TestCase(false)]
[TestCase(true)]
public void TestSliderBar(bool hasDescription) => createSliderBar(hasDescription);
private void createSliderBar(bool hasDescription = false)
{
AddStep("create component", () =>
{
LabelledSliderBar<double> component;
Child = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 500,
AutoSizeAxes = Axes.Y,
Child = component = new LabelledSliderBar<double>
{
Current = new BindableDouble(5)
{
MinValue = 0,
MaxValue = 10,
Precision = 1,
}
}
};
component.Label = "a sample component";
component.Description = hasDescription ? "this text describes the component" : string.Empty;
});
}
}
}

View File

@ -10,34 +10,34 @@ namespace osu.Game.Tournament.Components
{ {
public class DateTextBox : SettingsTextBox public class DateTextBox : SettingsTextBox
{ {
public new Bindable<DateTimeOffset> Bindable public new Bindable<DateTimeOffset> Current
{ {
get => bindable; get => current;
set set
{ {
bindable = value.GetBoundCopy(); current = value.GetBoundCopy();
bindable.BindValueChanged(dto => current.BindValueChanged(dto =>
base.Bindable.Value = dto.NewValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"), true); base.Current.Value = dto.NewValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"), true);
} }
} }
// hold a reference to the provided bindable so we don't have to in every settings section. // hold a reference to the provided bindable so we don't have to in every settings section.
private Bindable<DateTimeOffset> bindable = new Bindable<DateTimeOffset>(); private Bindable<DateTimeOffset> current = new Bindable<DateTimeOffset>();
public DateTextBox() public DateTextBox()
{ {
base.Bindable = new Bindable<string>(); base.Current = new Bindable<string>();
((OsuTextBox)Control).OnCommit += (sender, newText) => ((OsuTextBox)Control).OnCommit += (sender, newText) =>
{ {
try try
{ {
bindable.Value = DateTimeOffset.Parse(sender.Text); current.Value = DateTimeOffset.Parse(sender.Text);
} }
catch catch
{ {
// reset textbox content to its last valid state on a parse failure. // reset textbox content to its last valid state on a parse failure.
bindable.TriggerChange(); current.TriggerChange();
} }
}; };
} }

View File

@ -63,25 +63,25 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
LabelText = "Name", LabelText = "Name",
Width = 0.33f, Width = 0.33f,
Bindable = Model.Name Current = Model.Name
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Description", LabelText = "Description",
Width = 0.33f, Width = 0.33f,
Bindable = Model.Description Current = Model.Description
}, },
new DateTextBox new DateTextBox
{ {
LabelText = "Start Time", LabelText = "Start Time",
Width = 0.33f, Width = 0.33f,
Bindable = Model.StartDate Current = Model.StartDate
}, },
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Best of", LabelText = "Best of",
Width = 0.33f, Width = 0.33f,
Bindable = Model.BestOf Current = Model.BestOf
}, },
new SettingsButton new SettingsButton
{ {
@ -186,14 +186,14 @@ namespace osu.Game.Tournament.Screens.Editors
LabelText = "Beatmap ID", LabelText = "Beatmap ID",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = beatmapId, Current = beatmapId,
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Mods", LabelText = "Mods",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = mods, Current = mods,
}, },
drawableContainer = new Container drawableContainer = new Container
{ {

View File

@ -74,13 +74,13 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
LabelText = "Mod", LabelText = "Mod",
Width = 0.33f, Width = 0.33f,
Bindable = Model.Mod Current = Model.Mod
}, },
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Seed", LabelText = "Seed",
Width = 0.33f, Width = 0.33f,
Bindable = Model.Seed Current = Model.Seed
}, },
new SettingsButton new SettingsButton
{ {
@ -187,21 +187,21 @@ namespace osu.Game.Tournament.Screens.Editors
LabelText = "Beatmap ID", LabelText = "Beatmap ID",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = beatmapId, Current = beatmapId,
}, },
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Seed", LabelText = "Seed",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = beatmap.Seed Current = beatmap.Seed
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Score", LabelText = "Score",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = score, Current = score,
}, },
drawableContainer = new Container drawableContainer = new Container
{ {

View File

@ -102,31 +102,31 @@ namespace osu.Game.Tournament.Screens.Editors
{ {
LabelText = "Name", LabelText = "Name",
Width = 0.2f, Width = 0.2f,
Bindable = Model.FullName Current = Model.FullName
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Acronym", LabelText = "Acronym",
Width = 0.2f, Width = 0.2f,
Bindable = Model.Acronym Current = Model.Acronym
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Flag", LabelText = "Flag",
Width = 0.2f, Width = 0.2f,
Bindable = Model.FlagName Current = Model.FlagName
}, },
new SettingsTextBox new SettingsTextBox
{ {
LabelText = "Seed", LabelText = "Seed",
Width = 0.2f, Width = 0.2f,
Bindable = Model.Seed Current = Model.Seed
}, },
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Last Year Placement", LabelText = "Last Year Placement",
Width = 0.33f, Width = 0.33f,
Bindable = Model.LastYearPlacing Current = Model.LastYearPlacing
}, },
new SettingsButton new SettingsButton
{ {
@ -247,7 +247,7 @@ namespace osu.Game.Tournament.Screens.Editors
LabelText = "User ID", LabelText = "User ID",
RelativeSizeAxes = Axes.None, RelativeSizeAxes = Axes.None,
Width = 200, Width = 200,
Bindable = userId, Current = userId,
}, },
drawableContainer = new Container drawableContainer = new Container
{ {

View File

@ -113,13 +113,13 @@ namespace osu.Game.Tournament.Screens.Gameplay
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Chroma width", LabelText = "Chroma width",
Bindable = LadderInfo.ChromaKeyWidth, Current = LadderInfo.ChromaKeyWidth,
KeyboardStep = 1, KeyboardStep = 1,
}, },
new SettingsSlider<int> new SettingsSlider<int>
{ {
LabelText = "Players per team", LabelText = "Players per team",
Bindable = LadderInfo.PlayersPerTeam, Current = LadderInfo.PlayersPerTeam,
KeyboardStep = 1, KeyboardStep = 1,
} }
} }

View File

@ -51,15 +51,15 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
editorInfo.Selected.ValueChanged += selection => editorInfo.Selected.ValueChanged += selection =>
{ {
roundDropdown.Bindable = selection.NewValue?.Round; roundDropdown.Current = selection.NewValue?.Round;
losersCheckbox.Current = selection.NewValue?.Losers; losersCheckbox.Current = selection.NewValue?.Losers;
dateTimeBox.Bindable = selection.NewValue?.Date; dateTimeBox.Current = selection.NewValue?.Date;
team1Dropdown.Bindable = selection.NewValue?.Team1; team1Dropdown.Current = selection.NewValue?.Team1;
team2Dropdown.Bindable = selection.NewValue?.Team2; team2Dropdown.Current = selection.NewValue?.Team2;
}; };
roundDropdown.Bindable.ValueChanged += round => roundDropdown.Current.ValueChanged += round =>
{ {
if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value) if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value)
{ {
@ -88,7 +88,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{ {
public SettingsRoundDropdown(BindableList<TournamentRound> rounds) public SettingsRoundDropdown(BindableList<TournamentRound> rounds)
{ {
Bindable = new Bindable<TournamentRound>(); Current = new Bindable<TournamentRound>();
foreach (var r in rounds.Prepend(new TournamentRound())) foreach (var r in rounds.Prepend(new TournamentRound()))
add(r); add(r);

View File

@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
new SettingsTeamDropdown(LadderInfo.Teams) new SettingsTeamDropdown(LadderInfo.Teams)
{ {
LabelText = "Show specific team", LabelText = "Show specific team",
Bindable = currentTeam, Current = currentTeam,
} }
} }
} }

View File

@ -57,7 +57,7 @@ namespace osu.Game.Configuration
yield return new SettingsSlider<float> yield return new SettingsSlider<float>
{ {
LabelText = attr.Label, LabelText = attr.Label,
Bindable = bNumber, Current = bNumber,
KeyboardStep = 0.1f, KeyboardStep = 0.1f,
}; };
@ -67,7 +67,7 @@ namespace osu.Game.Configuration
yield return new SettingsSlider<double> yield return new SettingsSlider<double>
{ {
LabelText = attr.Label, LabelText = attr.Label,
Bindable = bNumber, Current = bNumber,
KeyboardStep = 0.1f, KeyboardStep = 0.1f,
}; };
@ -77,7 +77,7 @@ namespace osu.Game.Configuration
yield return new SettingsSlider<int> yield return new SettingsSlider<int>
{ {
LabelText = attr.Label, LabelText = attr.Label,
Bindable = bNumber Current = bNumber
}; };
break; break;
@ -86,7 +86,7 @@ namespace osu.Game.Configuration
yield return new SettingsCheckbox yield return new SettingsCheckbox
{ {
LabelText = attr.Label, LabelText = attr.Label,
Bindable = bBool Current = bBool
}; };
break; break;
@ -95,7 +95,7 @@ namespace osu.Game.Configuration
yield return new SettingsTextBox yield return new SettingsTextBox
{ {
LabelText = attr.Label, LabelText = attr.Label,
Bindable = bString Current = bString
}; };
break; break;
@ -105,7 +105,7 @@ namespace osu.Game.Configuration
var dropdown = (Drawable)Activator.CreateInstance(dropdownType); var dropdown = (Drawable)Activator.CreateInstance(dropdownType);
dropdownType.GetProperty(nameof(SettingsDropdown<object>.LabelText))?.SetValue(dropdown, attr.Label); dropdownType.GetProperty(nameof(SettingsDropdown<object>.LabelText))?.SetValue(dropdown, attr.Label);
dropdownType.GetProperty(nameof(SettingsDropdown<object>.Bindable))?.SetValue(dropdown, bindable); dropdownType.GetProperty(nameof(SettingsDropdown<object>.Current))?.SetValue(dropdown, bindable);
yield return dropdown; yield return dropdown;

View File

@ -0,0 +1,24 @@
// 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 System;
using osu.Framework.Graphics;
using osu.Game.Overlays.Settings;
namespace osu.Game.Graphics.UserInterfaceV2
{
public class LabelledSliderBar<TNumber> : LabelledComponent<SettingsSlider<TNumber>, TNumber>
where TNumber : struct, IEquatable<TNumber>, IComparable<TNumber>, IConvertible
{
public LabelledSliderBar()
: base(true)
{
}
protected override SettingsSlider<TNumber> CreateComponent() => new SettingsSlider<TNumber>
{
TransferValueOnCommit = true,
RelativeSizeAxes = Axes.X,
};
}
}

View File

@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
updateItems(); updateItems();
dropdown.Bindable = audio.AudioDevice; dropdown.Current = audio.AudioDevice;
audio.OnNewDevice += onDeviceChanged; audio.OnNewDevice += onDeviceChanged;
audio.OnLostDevice += onDeviceChanged; audio.OnLostDevice += onDeviceChanged;

View File

@ -21,23 +21,23 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Interface voices", LabelText = "Interface voices",
Bindable = config.GetBindable<bool>(OsuSetting.MenuVoice) Current = config.GetBindable<bool>(OsuSetting.MenuVoice)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "osu! music theme", LabelText = "osu! music theme",
Bindable = config.GetBindable<bool>(OsuSetting.MenuMusic) Current = config.GetBindable<bool>(OsuSetting.MenuMusic)
}, },
new SettingsDropdown<IntroSequence> new SettingsDropdown<IntroSequence>
{ {
LabelText = "Intro sequence", LabelText = "Intro sequence",
Bindable = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence), Current = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>() Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>()
}, },
new SettingsDropdown<BackgroundSource> new SettingsDropdown<BackgroundSource>
{ {
LabelText = "Background source", LabelText = "Background source",
Bindable = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource), Current = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource),
Items = Enum.GetValues(typeof(BackgroundSource)).Cast<BackgroundSource>() Items = Enum.GetValues(typeof(BackgroundSource)).Cast<BackgroundSource>()
} }
}; };

View File

@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
new SettingsSlider<double, OffsetSlider> new SettingsSlider<double, OffsetSlider>
{ {
LabelText = "Audio offset", LabelText = "Audio offset",
Bindable = config.GetBindable<double>(OsuSetting.AudioOffset), Current = config.GetBindable<double>(OsuSetting.AudioOffset),
KeyboardStep = 1f KeyboardStep = 1f
}, },
new SettingsButton new SettingsButton

View File

@ -20,28 +20,28 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Master", LabelText = "Master",
Bindable = audio.Volume, Current = audio.Volume,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Master (window inactive)", LabelText = "Master (window inactive)",
Bindable = config.GetBindable<double>(OsuSetting.VolumeInactive), Current = config.GetBindable<double>(OsuSetting.VolumeInactive),
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Effect", LabelText = "Effect",
Bindable = audio.VolumeSample, Current = audio.VolumeSample,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Music", LabelText = "Music",
Bindable = audio.VolumeTrack, Current = audio.VolumeTrack,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },

View File

@ -19,12 +19,12 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show log overlay", LabelText = "Show log overlay",
Bindable = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay) Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Bypass front-to-back render pass", LabelText = "Bypass front-to-back render pass",
Bindable = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass) Current = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass)
} }
}; };
} }

View File

@ -21,62 +21,62 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Background dim", LabelText = "Background dim",
Bindable = config.GetBindable<double>(OsuSetting.DimLevel), Current = config.GetBindable<double>(OsuSetting.DimLevel),
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<double> new SettingsSlider<double>
{ {
LabelText = "Background blur", LabelText = "Background blur",
Bindable = config.GetBindable<double>(OsuSetting.BlurLevel), Current = config.GetBindable<double>(OsuSetting.BlurLevel),
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Lighten playfield during breaks", LabelText = "Lighten playfield during breaks",
Bindable = config.GetBindable<bool>(OsuSetting.LightenDuringBreaks) Current = config.GetBindable<bool>(OsuSetting.LightenDuringBreaks)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show score overlay", LabelText = "Show score overlay",
Bindable = config.GetBindable<bool>(OsuSetting.ShowInterface) Current = config.GetBindable<bool>(OsuSetting.ShowInterface)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show difficulty graph on progress bar", LabelText = "Show difficulty graph on progress bar",
Bindable = config.GetBindable<bool>(OsuSetting.ShowProgressGraph) Current = config.GetBindable<bool>(OsuSetting.ShowProgressGraph)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show health display even when you can't fail", LabelText = "Show health display even when you can't fail",
Bindable = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail), Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
Keywords = new[] { "hp", "bar" } Keywords = new[] { "hp", "bar" }
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Fade playfield to red when health is low", LabelText = "Fade playfield to red when health is low",
Bindable = config.GetBindable<bool>(OsuSetting.FadePlayfieldWhenHealthLow), Current = config.GetBindable<bool>(OsuSetting.FadePlayfieldWhenHealthLow),
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Always show key overlay", LabelText = "Always show key overlay",
Bindable = config.GetBindable<bool>(OsuSetting.KeyOverlay) Current = config.GetBindable<bool>(OsuSetting.KeyOverlay)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Positional hitsounds", LabelText = "Positional hitsounds",
Bindable = config.GetBindable<bool>(OsuSetting.PositionalHitSounds) Current = config.GetBindable<bool>(OsuSetting.PositionalHitSounds)
}, },
new SettingsEnumDropdown<ScoreMeterType> new SettingsEnumDropdown<ScoreMeterType>
{ {
LabelText = "Score meter type", LabelText = "Score meter type",
Bindable = config.GetBindable<ScoreMeterType>(OsuSetting.ScoreMeter) Current = config.GetBindable<ScoreMeterType>(OsuSetting.ScoreMeter)
}, },
new SettingsEnumDropdown<ScoringMode> new SettingsEnumDropdown<ScoringMode>
{ {
LabelText = "Score display mode", LabelText = "Score display mode",
Bindable = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode) Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode)
} }
}; };
@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
Add(new SettingsCheckbox Add(new SettingsCheckbox
{ {
LabelText = "Disable Windows key during gameplay", LabelText = "Disable Windows key during gameplay",
Bindable = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey) Current = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey)
}); });
} }
} }

View File

@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Increase visibility of first object when visual impairment mods are enabled", LabelText = "Increase visibility of first object when visual impairment mods are enabled",
Bindable = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility), Current = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility),
}, },
}; };
} }

View File

@ -31,31 +31,31 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Right mouse drag to absolute scroll", LabelText = "Right mouse drag to absolute scroll",
Bindable = config.GetBindable<bool>(OsuSetting.SongSelectRightMouseScroll), Current = config.GetBindable<bool>(OsuSetting.SongSelectRightMouseScroll),
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show converted beatmaps", LabelText = "Show converted beatmaps",
Bindable = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps), Current = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps),
}, },
new SettingsSlider<double, StarsSlider> new SettingsSlider<double, StarsSlider>
{ {
LabelText = "Display beatmaps from", LabelText = "Display beatmaps from",
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum), Current = config.GetBindable<double>(OsuSetting.DisplayStarsMinimum),
KeyboardStep = 0.1f, KeyboardStep = 0.1f,
Keywords = new[] { "minimum", "maximum", "star", "difficulty" } Keywords = new[] { "minimum", "maximum", "star", "difficulty" }
}, },
new SettingsSlider<double, MaximumStarsSlider> new SettingsSlider<double, MaximumStarsSlider>
{ {
LabelText = "up to", LabelText = "up to",
Bindable = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum), Current = config.GetBindable<double>(OsuSetting.DisplayStarsMaximum),
KeyboardStep = 0.1f, KeyboardStep = 0.1f,
Keywords = new[] { "minimum", "maximum", "star", "difficulty" } Keywords = new[] { "minimum", "maximum", "star", "difficulty" }
}, },
new SettingsEnumDropdown<RandomSelectAlgorithm> new SettingsEnumDropdown<RandomSelectAlgorithm>
{ {
LabelText = "Random selection algorithm", LabelText = "Random selection algorithm",
Bindable = config.GetBindable<RandomSelectAlgorithm>(OsuSetting.RandomSelectAlgorithm), Current = config.GetBindable<RandomSelectAlgorithm>(OsuSetting.RandomSelectAlgorithm),
} }
}; };
} }

View File

@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Prefer metadata in original language", LabelText = "Prefer metadata in original language",
Bindable = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowUnicode) Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowUnicode)
}, },
}; };
} }

View File

@ -240,12 +240,12 @@ namespace osu.Game.Overlays.Settings.Sections.General
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Remember username", LabelText = "Remember username",
Bindable = config.GetBindable<bool>(OsuSetting.SaveUsername), Current = config.GetBindable<bool>(OsuSetting.SaveUsername),
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Stay signed in", LabelText = "Stay signed in",
Bindable = config.GetBindable<bool>(OsuSetting.SavePassword), Current = config.GetBindable<bool>(OsuSetting.SavePassword),
}, },
new Container new Container
{ {

View File

@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
Add(new SettingsEnumDropdown<ReleaseStream> Add(new SettingsEnumDropdown<ReleaseStream>
{ {
LabelText = "Release stream", LabelText = "Release stream",
Bindable = config.GetBindable<ReleaseStream>(OsuSetting.ReleaseStream), Current = config.GetBindable<ReleaseStream>(OsuSetting.ReleaseStream),
}); });
if (updateManager?.CanCheckForUpdate == true) if (updateManager?.CanCheckForUpdate == true)

View File

@ -19,22 +19,22 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Storyboard / Video", LabelText = "Storyboard / Video",
Bindable = config.GetBindable<bool>(OsuSetting.ShowStoryboard) Current = config.GetBindable<bool>(OsuSetting.ShowStoryboard)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Hit Lighting", LabelText = "Hit Lighting",
Bindable = config.GetBindable<bool>(OsuSetting.HitLighting) Current = config.GetBindable<bool>(OsuSetting.HitLighting)
}, },
new SettingsEnumDropdown<ScreenshotFormat> new SettingsEnumDropdown<ScreenshotFormat>
{ {
LabelText = "Screenshot format", LabelText = "Screenshot format",
Bindable = config.GetBindable<ScreenshotFormat>(OsuSetting.ScreenshotFormat) Current = config.GetBindable<ScreenshotFormat>(OsuSetting.ScreenshotFormat)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show menu cursor in screenshots", LabelText = "Show menu cursor in screenshots",
Bindable = config.GetBindable<bool>(OsuSetting.ScreenshotCaptureMenuCursor) Current = config.GetBindable<bool>(OsuSetting.ScreenshotCaptureMenuCursor)
} }
}; };
} }

View File

@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
windowModeDropdown = new SettingsDropdown<WindowMode> windowModeDropdown = new SettingsDropdown<WindowMode>
{ {
LabelText = "Screen mode", LabelText = "Screen mode",
Bindable = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode), Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
ItemSource = windowModes, ItemSource = windowModes,
}, },
resolutionSettingsContainer = new Container resolutionSettingsContainer = new Container
@ -74,14 +74,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{ {
LabelText = "UI Scaling", LabelText = "UI Scaling",
TransferValueOnCommit = true, TransferValueOnCommit = true,
Bindable = osuConfig.GetBindable<float>(OsuSetting.UIScale), Current = osuConfig.GetBindable<float>(OsuSetting.UIScale),
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
Keywords = new[] { "scale", "letterbox" }, Keywords = new[] { "scale", "letterbox" },
}, },
new SettingsEnumDropdown<ScalingMode> new SettingsEnumDropdown<ScalingMode>
{ {
LabelText = "Screen Scaling", LabelText = "Screen Scaling",
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling), Current = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
Keywords = new[] { "scale", "letterbox" }, Keywords = new[] { "scale", "letterbox" },
}, },
scalingSettings = new FillFlowContainer<SettingsSlider<float>> scalingSettings = new FillFlowContainer<SettingsSlider<float>>
@ -97,28 +97,28 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
new SettingsSlider<float> new SettingsSlider<float>
{ {
LabelText = "Horizontal position", LabelText = "Horizontal position",
Bindable = scalingPositionX, Current = scalingPositionX,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<float> new SettingsSlider<float>
{ {
LabelText = "Vertical position", LabelText = "Vertical position",
Bindable = scalingPositionY, Current = scalingPositionY,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<float> new SettingsSlider<float>
{ {
LabelText = "Horizontal scale", LabelText = "Horizontal scale",
Bindable = scalingSizeX, Current = scalingSizeX,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
new SettingsSlider<float> new SettingsSlider<float>
{ {
LabelText = "Vertical scale", LabelText = "Vertical scale",
Bindable = scalingSizeY, Current = scalingSizeY,
KeyboardStep = 0.01f, KeyboardStep = 0.01f,
DisplayAsPercentage = true DisplayAsPercentage = true
}, },
@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
}, },
}; };
scalingSettings.ForEach(s => bindPreviewEvent(s.Bindable)); scalingSettings.ForEach(s => bindPreviewEvent(s.Current));
var resolutions = getResolutions(); var resolutions = getResolutions();
@ -137,10 +137,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
LabelText = "Resolution", LabelText = "Resolution",
ShowsDefaultIndicator = false, ShowsDefaultIndicator = false,
Items = resolutions, Items = resolutions,
Bindable = sizeFullscreen Current = sizeFullscreen
}; };
windowModeDropdown.Bindable.BindValueChanged(mode => windowModeDropdown.Current.BindValueChanged(mode =>
{ {
if (mode.NewValue == WindowMode.Fullscreen) if (mode.NewValue == WindowMode.Fullscreen)
{ {

View File

@ -23,17 +23,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
new SettingsEnumDropdown<FrameSync> new SettingsEnumDropdown<FrameSync>
{ {
LabelText = "Frame limiter", LabelText = "Frame limiter",
Bindable = config.GetBindable<FrameSync>(FrameworkSetting.FrameSync) Current = config.GetBindable<FrameSync>(FrameworkSetting.FrameSync)
}, },
new SettingsEnumDropdown<ExecutionMode> new SettingsEnumDropdown<ExecutionMode>
{ {
LabelText = "Threading mode", LabelText = "Threading mode",
Bindable = config.GetBindable<ExecutionMode>(FrameworkSetting.ExecutionMode) Current = config.GetBindable<ExecutionMode>(FrameworkSetting.ExecutionMode)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Show FPS", LabelText = "Show FPS",
Bindable = osuConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay) Current = osuConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay)
}, },
}; };
} }

View File

@ -20,17 +20,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Rotate cursor when dragging", LabelText = "Rotate cursor when dragging",
Bindable = config.GetBindable<bool>(OsuSetting.CursorRotation) Current = config.GetBindable<bool>(OsuSetting.CursorRotation)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Parallax", LabelText = "Parallax",
Bindable = config.GetBindable<bool>(OsuSetting.MenuParallax) Current = config.GetBindable<bool>(OsuSetting.MenuParallax)
}, },
new SettingsSlider<float, TimeSlider> new SettingsSlider<float, TimeSlider>
{ {
LabelText = "Hold-to-confirm activation time", LabelText = "Hold-to-confirm activation time",
Bindable = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay), Current = config.GetBindable<float>(OsuSetting.UIHoldActivationDelay),
KeyboardStep = 50 KeyboardStep = 50
}, },
}; };

View File

@ -35,32 +35,32 @@ namespace osu.Game.Overlays.Settings.Sections.Input
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Raw input", LabelText = "Raw input",
Bindable = rawInputToggle Current = rawInputToggle
}, },
new SensitivitySetting new SensitivitySetting
{ {
LabelText = "Cursor sensitivity", LabelText = "Cursor sensitivity",
Bindable = sensitivityBindable Current = sensitivityBindable
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Map absolute input to window", LabelText = "Map absolute input to window",
Bindable = config.GetBindable<bool>(FrameworkSetting.MapAbsoluteInputToWindow) Current = config.GetBindable<bool>(FrameworkSetting.MapAbsoluteInputToWindow)
}, },
new SettingsEnumDropdown<OsuConfineMouseMode> new SettingsEnumDropdown<OsuConfineMouseMode>
{ {
LabelText = "Confine mouse cursor to window", LabelText = "Confine mouse cursor to window",
Bindable = osuConfig.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode) Current = osuConfig.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Disable mouse wheel during gameplay", LabelText = "Disable mouse wheel during gameplay",
Bindable = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel) Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Disable mouse buttons during gameplay", LabelText = "Disable mouse buttons during gameplay",
Bindable = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons) Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
}, },
}; };

View File

@ -19,13 +19,13 @@ namespace osu.Game.Overlays.Settings.Sections.Online
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Warn about opening external links", LabelText = "Warn about opening external links",
Bindable = config.GetBindable<bool>(OsuSetting.ExternalLinkWarning) Current = config.GetBindable<bool>(OsuSetting.ExternalLinkWarning)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Prefer downloads without video", LabelText = "Prefer downloads without video",
Keywords = new[] { "no-video" }, Keywords = new[] { "no-video" },
Bindable = config.GetBindable<bool>(OsuSetting.PreferNoVideo) Current = config.GetBindable<bool>(OsuSetting.PreferNoVideo)
}, },
}; };
} }

View File

@ -47,29 +47,29 @@ namespace osu.Game.Overlays.Settings.Sections
new SettingsSlider<float, SizeSlider> new SettingsSlider<float, SizeSlider>
{ {
LabelText = "Menu cursor size", LabelText = "Menu cursor size",
Bindable = config.GetBindable<float>(OsuSetting.MenuCursorSize), Current = config.GetBindable<float>(OsuSetting.MenuCursorSize),
KeyboardStep = 0.01f KeyboardStep = 0.01f
}, },
new SettingsSlider<float, SizeSlider> new SettingsSlider<float, SizeSlider>
{ {
LabelText = "Gameplay cursor size", LabelText = "Gameplay cursor size",
Bindable = config.GetBindable<float>(OsuSetting.GameplayCursorSize), Current = config.GetBindable<float>(OsuSetting.GameplayCursorSize),
KeyboardStep = 0.01f KeyboardStep = 0.01f
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Adjust gameplay cursor size based on current beatmap", LabelText = "Adjust gameplay cursor size based on current beatmap",
Bindable = config.GetBindable<bool>(OsuSetting.AutoCursorSize) Current = config.GetBindable<bool>(OsuSetting.AutoCursorSize)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Beatmap skins", LabelText = "Beatmap skins",
Bindable = config.GetBindable<bool>(OsuSetting.BeatmapSkins) Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins)
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
LabelText = "Beatmap hitsounds", LabelText = "Beatmap hitsounds",
Bindable = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds) Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds)
}, },
}; };
@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Settings.Sections
config.BindWith(OsuSetting.Skin, configBindable); config.BindWith(OsuSetting.Skin, configBindable);
skinDropdown.Bindable = dropdownBindable; skinDropdown.Current = dropdownBindable;
skinDropdown.Items = skins.GetAllUsableSkins().ToArray(); skinDropdown.Items = skins.GetAllUsableSkins().ToArray();
// Todo: This should not be necessary when OsuConfigManager is databased // Todo: This should not be necessary when OsuConfigManager is databased

View File

@ -21,7 +21,7 @@ using osuTK;
namespace osu.Game.Overlays.Settings namespace osu.Game.Overlays.Settings
{ {
public abstract class SettingsItem<T> : Container, IFilterable, ISettingsItem public abstract class SettingsItem<T> : Container, IFilterable, ISettingsItem, IHasCurrentValue<T>
{ {
protected abstract Drawable CreateControl(); protected abstract Drawable CreateControl();
@ -54,7 +54,14 @@ namespace osu.Game.Overlays.Settings
} }
} }
public virtual Bindable<T> Bindable [Obsolete("Use Current instead")] // Can be removed 20210406
public Bindable<T> Bindable
{
get => Current;
set => Current = value;
}
public virtual Bindable<T> Current
{ {
get => controlWithCurrent.Current; get => controlWithCurrent.Current;
set => controlWithCurrent.Current = value; set => controlWithCurrent.Current = value;

View File

@ -199,7 +199,40 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
base.Update(); base.Update();
// no bindable so we perform this every update // no bindable so we perform this every update
Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); float duration = (float)(HitObject.GetEndTime() - HitObject.StartTime);
if (Width != duration)
{
Width = duration;
// kind of haphazard but yeah, no bindables.
if (HitObject is IHasRepeats repeats)
updateRepeats(repeats);
}
}
private Container repeatsContainer;
private void updateRepeats(IHasRepeats repeats)
{
repeatsContainer?.Expire();
mainComponents.Add(repeatsContainer = new Container
{
RelativeSizeAxes = Axes.Both,
});
for (int i = 0; i < repeats.RepeatCount; i++)
{
repeatsContainer.Add(new Circle
{
Size = new Vector2(circle_size / 2),
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
RelativePositionAxes = Axes.X,
X = (float)(i + 1) / (repeats.RepeatCount + 1),
});
}
} }
protected override bool ShouldBeConsideredForInput(Drawable child) => true; protected override bool ShouldBeConsideredForInput(Drawable child) => true;

View File

@ -589,7 +589,7 @@ namespace osu.Game.Screens.Edit
private void seek(UIEvent e, int direction) private void seek(UIEvent e, int direction)
{ {
double amount = e.ShiftPressed ? 2 : 1; double amount = e.ShiftPressed ? 4 : 1;
if (direction < 1) if (direction < 1)
clock.SeekBackward(!clock.IsRunning, amount); clock.SeekBackward(!clock.IsRunning, amount);

View File

@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit
/// </summary> /// </summary>
/// <param name="snapped">Whether to snap to the closest beat after seeking.</param> /// <param name="snapped">Whether to snap to the closest beat after seeking.</param>
/// <param name="amount">The relative amount (magnitude) which should be seeked.</param> /// <param name="amount">The relative amount (magnitude) which should be seeked.</param>
public void SeekBackward(bool snapped = false, double amount = 1) => seek(-1, snapped, amount); public void SeekBackward(bool snapped = false, double amount = 1) => seek(-1, snapped, amount + (IsRunning ? 1.5 : 0));
/// <summary> /// <summary>
/// Seeks forwards by one beat length. /// Seeks forwards by one beat length.

View File

@ -0,0 +1,73 @@
// 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 System;
using System.IO;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Screens.Edit.Setup
{
/// <summary>
/// A labelled textbox which reveals an inline file chooser when clicked.
/// </summary>
internal class FileChooserLabelledTextBox : LabelledTextBox
{
public Container Target;
private readonly IBindable<FileInfo> currentFile = new Bindable<FileInfo>();
public FileChooserLabelledTextBox()
{
currentFile.BindValueChanged(onFileSelected);
}
private void onFileSelected(ValueChangedEvent<FileInfo> file)
{
if (file.NewValue == null)
return;
Target.Clear();
Current.Value = file.NewValue.FullName;
}
protected override OsuTextBox CreateTextBox() =>
new FileChooserOsuTextBox
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
CornerRadius = CORNER_RADIUS,
OnFocused = DisplayFileChooser
};
public void DisplayFileChooser()
{
Target.Child = new FileSelector(validFileExtensions: ResourcesSection.AudioExtensions)
{
RelativeSizeAxes = Axes.X,
Height = 400,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
CurrentFile = { BindTarget = currentFile }
};
}
internal class FileChooserOsuTextBox : OsuTextBox
{
public Action OnFocused;
protected override void OnFocus(FocusEvent e)
{
OnFocused?.Invoke();
base.OnFocus(e);
GetContainingInputManager().TriggerFocusContention(this);
}
}
}
}

View File

@ -0,0 +1,71 @@
// 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 System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Screens.Edit.Setup
{
internal class MetadataSection : SetupSection
{
private LabelledTextBox artistTextBox;
private LabelledTextBox titleTextBox;
private LabelledTextBox creatorTextBox;
private LabelledTextBox difficultyTextBox;
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "Beatmap metadata"
},
artistTextBox = new LabelledTextBox
{
Label = "Artist",
Current = { Value = Beatmap.Value.Metadata.Artist },
TabbableContentContainer = this
},
titleTextBox = new LabelledTextBox
{
Label = "Title",
Current = { Value = Beatmap.Value.Metadata.Title },
TabbableContentContainer = this
},
creatorTextBox = new LabelledTextBox
{
Label = "Creator",
Current = { Value = Beatmap.Value.Metadata.AuthorString },
TabbableContentContainer = this
},
difficultyTextBox = new LabelledTextBox
{
Label = "Difficulty Name",
Current = { Value = Beatmap.Value.BeatmapInfo.Version },
TabbableContentContainer = this
},
};
foreach (var item in Children.OfType<LabelledTextBox>())
item.OnCommit += onCommit;
}
private void onCommit(TextBox sender, bool newText)
{
if (!newText) return;
// for now, update these on commit rather than making BeatmapMetadata bindables.
// after switching database engines we can reconsider if switching to bindables is a good direction.
Beatmap.Value.Metadata.Artist = artistTextBox.Current.Value;
Beatmap.Value.Metadata.Title = titleTextBox.Current.Value;
Beatmap.Value.Metadata.AuthorString = creatorTextBox.Current.Value;
Beatmap.Value.BeatmapInfo.Version = difficultyTextBox.Current.Value;
}
}
}

View File

@ -0,0 +1,211 @@
// 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 System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
namespace osu.Game.Screens.Edit.Setup
{
internal class ResourcesSection : SetupSection, ICanAcceptFiles
{
private LabelledTextBox audioTrackTextBox;
private Container backgroundSpriteContainer;
public IEnumerable<string> HandledExtensions => ImageExtensions.Concat(AudioExtensions);
public static string[] ImageExtensions { get; } = { ".jpg", ".jpeg", ".png" };
public static string[] AudioExtensions { get; } = { ".mp3", ".ogg" };
[Resolved]
private OsuGameBase game { get; set; }
[Resolved]
private MusicController music { get; set; }
[Resolved]
private BeatmapManager beatmaps { get; set; }
[Resolved(canBeNull: true)]
private Editor editor { get; set; }
[BackgroundDependencyLoader]
private void load()
{
Container audioTrackFileChooserContainer = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
};
Children = new Drawable[]
{
backgroundSpriteContainer = new Container
{
RelativeSizeAxes = Axes.X,
Height = 250,
Masking = true,
CornerRadius = 10,
},
new OsuSpriteText
{
Text = "Resources"
},
audioTrackTextBox = new FileChooserLabelledTextBox
{
Label = "Audio Track",
Current = { Value = Beatmap.Value.Metadata.AudioFile ?? "Click to select a track" },
Target = audioTrackFileChooserContainer,
TabbableContentContainer = this
},
audioTrackFileChooserContainer,
};
updateBackgroundSprite();
audioTrackTextBox.Current.BindValueChanged(audioTrackChanged);
}
Task ICanAcceptFiles.Import(params string[] paths)
{
Schedule(() =>
{
var firstFile = new FileInfo(paths.First());
if (ImageExtensions.Contains(firstFile.Extension))
{
ChangeBackgroundImage(firstFile.FullName);
}
else if (AudioExtensions.Contains(firstFile.Extension))
{
audioTrackTextBox.Text = firstFile.FullName;
}
});
return Task.CompletedTask;
}
protected override void LoadComplete()
{
base.LoadComplete();
game.RegisterImportHandler(this);
}
public bool ChangeBackgroundImage(string path)
{
var info = new FileInfo(path);
if (!info.Exists)
return false;
var set = Beatmap.Value.BeatmapSetInfo;
// remove the previous background for now.
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
var oldFile = set.Files.FirstOrDefault(f => f.Filename == Beatmap.Value.Metadata.BackgroundFile);
using (var stream = info.OpenRead())
{
if (oldFile != null)
beatmaps.ReplaceFile(set, oldFile, stream, info.Name);
else
beatmaps.AddFile(set, stream, info.Name);
}
Beatmap.Value.Metadata.BackgroundFile = info.Name;
updateBackgroundSprite();
return true;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
game?.UnregisterImportHandler(this);
}
public bool ChangeAudioTrack(string path)
{
var info = new FileInfo(path);
if (!info.Exists)
return false;
var set = Beatmap.Value.BeatmapSetInfo;
// remove the previous audio track for now.
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
var oldFile = set.Files.FirstOrDefault(f => f.Filename == Beatmap.Value.Metadata.AudioFile);
using (var stream = info.OpenRead())
{
if (oldFile != null)
beatmaps.ReplaceFile(set, oldFile, stream, info.Name);
else
beatmaps.AddFile(set, stream, info.Name);
}
Beatmap.Value.Metadata.AudioFile = info.Name;
music.ReloadCurrentTrack();
editor?.UpdateClockSource();
return true;
}
private void audioTrackChanged(ValueChangedEvent<string> filePath)
{
if (!ChangeAudioTrack(filePath.NewValue))
audioTrackTextBox.Current.Value = filePath.OldValue;
}
private void updateBackgroundSprite()
{
LoadComponentAsync(new BeatmapBackgroundSprite(Beatmap.Value)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fill,
}, background =>
{
if (background.Texture != null)
backgroundSpriteContainer.Child = background;
else
{
backgroundSpriteContainer.Children = new Drawable[]
{
new Box
{
Colour = Colours.GreySeafoamDarker,
RelativeSizeAxes = Axes.Both,
},
new OsuTextFlowContainer(t => t.Font = OsuFont.Default.With(size: 24))
{
Text = "Drag image here to set beatmap background!",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.X,
}
};
}
background.FadeInFromZero(500);
});
}
}
}

View File

@ -1,73 +1,33 @@
// 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.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays; using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit.Setup namespace osu.Game.Screens.Edit.Setup
{ {
public class SetupScreen : EditorScreen, ICanAcceptFiles public class SetupScreen : EditorScreen
{ {
public IEnumerable<string> HandledExtensions => ImageExtensions.Concat(AudioExtensions);
public static string[] ImageExtensions { get; } = { ".jpg", ".jpeg", ".png" };
public static string[] AudioExtensions { get; } = { ".mp3", ".ogg" };
private FillFlowContainer flow;
private LabelledTextBox artistTextBox;
private LabelledTextBox titleTextBox;
private LabelledTextBox creatorTextBox;
private LabelledTextBox difficultyTextBox;
private LabelledTextBox audioTrackTextBox;
private Container backgroundSpriteContainer;
[Resolved] [Resolved]
private OsuGameBase game { get; set; } private OsuColour colours { get; set; }
[Resolved] [Cached]
private MusicController music { get; set; } protected readonly OverlayColourProvider ColourProvider;
[Resolved]
private BeatmapManager beatmaps { get; set; }
[Resolved(canBeNull: true)]
private Editor editor { get; set; }
public SetupScreen() public SetupScreen()
: base(EditorScreenMode.SongSetup) : base(EditorScreenMode.SongSetup)
{ {
ColourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load()
{ {
Container audioTrackFileChooserContainer = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
};
Child = new Container Child = new Container
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
@ -84,253 +44,33 @@ namespace osu.Game.Screens.Edit.Setup
Colour = colours.GreySeafoamDark, Colour = colours.GreySeafoamDark,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
new OsuScrollContainer new SectionsContainer<SetupSection>
{ {
FixedHeader = new SetupScreenHeader(),
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(10), Children = new SetupSection[]
Child = flow = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.X, new ResourcesSection(),
AutoSizeAxes = Axes.Y, new MetadataSection(),
Spacing = new Vector2(20),
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
backgroundSpriteContainer = new Container
{
RelativeSizeAxes = Axes.X,
Height = 250,
Masking = true,
CornerRadius = 10,
},
new OsuSpriteText
{
Text = "Resources"
},
audioTrackTextBox = new FileChooserLabelledTextBox
{
Label = "Audio Track",
Current = { Value = Beatmap.Value.Metadata.AudioFile ?? "Click to select a track" },
Target = audioTrackFileChooserContainer,
TabbableContentContainer = this
},
audioTrackFileChooserContainer,
new OsuSpriteText
{
Text = "Beatmap metadata"
},
artistTextBox = new LabelledTextBox
{
Label = "Artist",
Current = { Value = Beatmap.Value.Metadata.Artist },
TabbableContentContainer = this
},
titleTextBox = new LabelledTextBox
{
Label = "Title",
Current = { Value = Beatmap.Value.Metadata.Title },
TabbableContentContainer = this
},
creatorTextBox = new LabelledTextBox
{
Label = "Creator",
Current = { Value = Beatmap.Value.Metadata.AuthorString },
TabbableContentContainer = this
},
difficultyTextBox = new LabelledTextBox
{
Label = "Difficulty Name",
Current = { Value = Beatmap.Value.BeatmapInfo.Version },
TabbableContentContainer = this
},
} }
}, },
},
} }
} }
}; };
updateBackgroundSprite();
audioTrackTextBox.Current.BindValueChanged(audioTrackChanged);
foreach (var item in flow.OfType<LabelledTextBox>())
item.OnCommit += onCommit;
}
Task ICanAcceptFiles.Import(params string[] paths)
{
Schedule(() =>
{
var firstFile = new FileInfo(paths.First());
if (ImageExtensions.Contains(firstFile.Extension))
{
ChangeBackgroundImage(firstFile.FullName);
}
else if (AudioExtensions.Contains(firstFile.Extension))
{
audioTrackTextBox.Text = firstFile.FullName;
}
});
return Task.CompletedTask;
}
private void updateBackgroundSprite()
{
LoadComponentAsync(new BeatmapBackgroundSprite(Beatmap.Value)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
FillMode = FillMode.Fill,
}, background =>
{
backgroundSpriteContainer.Child = background;
background.FadeInFromZero(500);
});
}
protected override void LoadComplete()
{
base.LoadComplete();
game.RegisterImportHandler(this);
}
public bool ChangeBackgroundImage(string path)
{
var info = new FileInfo(path);
if (!info.Exists)
return false;
var set = Beatmap.Value.BeatmapSetInfo;
// remove the previous background for now.
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
var oldFile = set.Files.FirstOrDefault(f => f.Filename == Beatmap.Value.Metadata.BackgroundFile);
using (var stream = info.OpenRead())
{
if (oldFile != null)
beatmaps.ReplaceFile(set, oldFile, stream, info.Name);
else
beatmaps.AddFile(set, stream, info.Name);
}
Beatmap.Value.Metadata.BackgroundFile = info.Name;
updateBackgroundSprite();
return true;
}
public bool ChangeAudioTrack(string path)
{
var info = new FileInfo(path);
if (!info.Exists)
return false;
var set = Beatmap.Value.BeatmapSetInfo;
// remove the previous audio track for now.
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
var oldFile = set.Files.FirstOrDefault(f => f.Filename == Beatmap.Value.Metadata.AudioFile);
using (var stream = info.OpenRead())
{
if (oldFile != null)
beatmaps.ReplaceFile(set, oldFile, stream, info.Name);
else
beatmaps.AddFile(set, stream, info.Name);
}
Beatmap.Value.Metadata.AudioFile = info.Name;
music.ReloadCurrentTrack();
editor?.UpdateClockSource();
return true;
}
private void audioTrackChanged(ValueChangedEvent<string> filePath)
{
if (!ChangeAudioTrack(filePath.NewValue))
audioTrackTextBox.Current.Value = filePath.OldValue;
}
private void onCommit(TextBox sender, bool newText)
{
if (!newText) return;
// for now, update these on commit rather than making BeatmapMetadata bindables.
// after switching database engines we can reconsider if switching to bindables is a good direction.
Beatmap.Value.Metadata.Artist = artistTextBox.Current.Value;
Beatmap.Value.Metadata.Title = titleTextBox.Current.Value;
Beatmap.Value.Metadata.AuthorString = creatorTextBox.Current.Value;
Beatmap.Value.BeatmapInfo.Version = difficultyTextBox.Current.Value;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
game?.UnregisterImportHandler(this);
} }
} }
internal class FileChooserLabelledTextBox : LabelledTextBox internal class SetupScreenHeader : OverlayHeader
{ {
public Container Target; protected override OverlayTitle CreateTitle() => new SetupScreenTitle();
private readonly IBindable<FileInfo> currentFile = new Bindable<FileInfo>(); private class SetupScreenTitle : OverlayTitle
public FileChooserLabelledTextBox()
{ {
currentFile.BindValueChanged(onFileSelected); public SetupScreenTitle()
}
private void onFileSelected(ValueChangedEvent<FileInfo> file)
{ {
if (file.NewValue == null) Title = "beatmap setup";
return; Description = "change general settings of your beatmap";
IconTexture = "Icons/Hexacons/social";
Target.Clear();
Current.Value = file.NewValue.FullName;
}
protected override OsuTextBox CreateTextBox() =>
new FileChooserOsuTextBox
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
CornerRadius = CORNER_RADIUS,
OnFocused = DisplayFileChooser
};
public void DisplayFileChooser()
{
Target.Child = new FileSelector(validFileExtensions: SetupScreen.AudioExtensions)
{
RelativeSizeAxes = Axes.X,
Height = 400,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
CurrentFile = { BindTarget = currentFile }
};
}
internal class FileChooserOsuTextBox : OsuTextBox
{
public Action OnFocused;
protected override void OnFocus(FocusEvent e)
{
OnFocused?.Invoke();
base.OnFocus(e);
GetContainingInputManager().TriggerFocusContention(this);
} }
} }
} }

View File

@ -0,0 +1,42 @@
// 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.Game.Beatmaps;
using osu.Game.Graphics;
using osuTK;
namespace osu.Game.Screens.Edit.Setup
{
internal class SetupSection : Container
{
private readonly FillFlowContainer flow;
[Resolved]
protected OsuColour Colours { get; private set; }
[Resolved]
protected IBindable<WorkingBeatmap> Beatmap { get; private set; }
protected override Container<Drawable> Content => flow;
public SetupSection()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Padding = new MarginPadding(10);
InternalChild = flow = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(20),
Direction = FillDirection.Vertical,
};
}
}
}

View File

@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings;
namespace osu.Game.Screens.Edit.Timing namespace osu.Game.Screens.Edit.Timing
{ {
internal class SliderWithTextBoxInput<T> : CompositeDrawable, IHasCurrentValue<T> public class SliderWithTextBoxInput<T> : CompositeDrawable, IHasCurrentValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{ {
private readonly SettingsSlider<T> slider; private readonly SettingsSlider<T> slider;
@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Timing
try try
{ {
slider.Bindable.Parse(t.Text); slider.Current.Parse(t.Text);
} }
catch catch
{ {
@ -71,8 +71,8 @@ namespace osu.Game.Screens.Edit.Timing
public Bindable<T> Current public Bindable<T> Current
{ {
get => slider.Bindable; get => slider.Current;
set => slider.Bindable = value; set => slider.Current = value;
} }
} }
} }

View File

@ -36,14 +36,14 @@ namespace osu.Game.Screens.Edit.Timing
{ {
if (point.NewValue != null) if (point.NewValue != null)
{ {
bpmSlider.Bindable = point.NewValue.BeatLengthBindable; bpmSlider.Current = point.NewValue.BeatLengthBindable;
bpmSlider.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); bpmSlider.Current.BindValueChanged(_ => ChangeHandler?.SaveState());
bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable; bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable;
// no need to hook change handler here as it's the same bindable as above // no need to hook change handler here as it's the same bindable as above
timeSignature.Bindable = point.NewValue.TimeSignatureBindable; timeSignature.Current = point.NewValue.TimeSignatureBindable;
timeSignature.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); timeSignature.Current.BindValueChanged(_ => ChangeHandler?.SaveState());
} }
} }
@ -121,14 +121,14 @@ namespace osu.Game.Screens.Edit.Timing
beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true); beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true);
bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue));
base.Bindable = bpmBindable; base.Current = bpmBindable;
TransferValueOnCommit = true; TransferValueOnCommit = true;
} }
public override Bindable<double> Bindable public override Bindable<double> Current
{ {
get => base.Bindable; get => base.Current;
set set
{ {
// incoming will be beat length, not bpm // incoming will be beat length, not bpm

View File

@ -51,14 +51,14 @@ namespace osu.Game.Screens.Play.PlayerSettings
} }
}, },
}, },
rateSlider = new PlayerSliderBar<double> { Bindable = UserPlaybackRate } rateSlider = new PlayerSliderBar<double> { Current = UserPlaybackRate }
}; };
} }
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
rateSlider.Bindable.BindValueChanged(multiplier => multiplierText.Text = $"{multiplier.NewValue:0.0}x", true); rateSlider.Current.BindValueChanged(multiplier => multiplierText.Text = $"{multiplier.NewValue:0.0}x", true);
} }
} }
} }

View File

@ -50,8 +50,8 @@ namespace osu.Game.Screens.Play.PlayerSettings
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
dimSliderBar.Bindable = config.GetBindable<double>(OsuSetting.DimLevel); dimSliderBar.Current = config.GetBindable<double>(OsuSetting.DimLevel);
blurSliderBar.Bindable = config.GetBindable<double>(OsuSetting.BlurLevel); blurSliderBar.Current = config.GetBindable<double>(OsuSetting.BlurLevel);
showStoryboardToggle.Current = config.GetBindable<bool>(OsuSetting.ShowStoryboard); showStoryboardToggle.Current = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
beatmapSkinsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins); beatmapSkinsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins);
beatmapHitsoundsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds); beatmapHitsoundsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds);