From f98e96e45b22b3b34e56543f2249d43e62585d5f Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 16 Aug 2020 10:52:23 +0930 Subject: [PATCH 01/62] Add osu!-specific enum for confine mouse mode --- osu.Game/Input/OsuConfineMouseMode.cs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 osu.Game/Input/OsuConfineMouseMode.cs diff --git a/osu.Game/Input/OsuConfineMouseMode.cs b/osu.Game/Input/OsuConfineMouseMode.cs new file mode 100644 index 0000000000..32b456395c --- /dev/null +++ b/osu.Game/Input/OsuConfineMouseMode.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.ComponentModel; +using osu.Framework.Input; + +namespace osu.Game.Input +{ + /// + /// Determines the situations in which the mouse cursor should be confined to the window. + /// Expands upon by providing the option to confine during gameplay. + /// + public enum OsuConfineMouseMode + { + /// + /// The mouse cursor will be free to move outside the game window. + /// + Never, + + /// + /// The mouse cursor will be locked to the window bounds while in fullscreen mode. + /// + Fullscreen, + + /// + /// The mouse cursor will be locked to the window bounds during gameplay, + /// but may otherwise move freely. + /// + [Description("During Gameplay")] + DuringGameplay, + + /// + /// The mouse cursor will always be locked to the window bounds while the game has focus. + /// + Always + } +} From 322d179076a383cf7fd2e7506e27189fba025278 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 16 Aug 2020 11:04:28 +0930 Subject: [PATCH 02/62] Replace settings item with osu! confine cursor mode --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index a8a8794320..9ef846c974 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -6,6 +6,7 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; using osu.Framework.Platform; +using osu.Game.Input; using osu.Game.Overlays; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select; @@ -66,6 +67,7 @@ namespace osu.Game.Configuration Set(OsuSetting.MouseDisableButtons, false); Set(OsuSetting.MouseDisableWheel, false); + Set(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.DuringGameplay); // Graphics Set(OsuSetting.ShowFpsDisplay, false); @@ -191,6 +193,7 @@ namespace osu.Game.Configuration FadePlayfieldWhenHealthLow, MouseDisableButtons, MouseDisableWheel, + ConfineMouseMode, AudioOffset, VolumeInactive, MenuMusic, diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index d27ab63fb7..0d98508e3b 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -6,9 +6,9 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Input; namespace osu.Game.Overlays.Settings.Sections.Input { @@ -47,10 +47,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input LabelText = "Map absolute input to window", Bindable = config.GetBindable(FrameworkSetting.MapAbsoluteInputToWindow) }, - new SettingsEnumDropdown + new SettingsEnumDropdown { LabelText = "Confine mouse cursor to window", - Bindable = config.GetBindable(FrameworkSetting.ConfineMouseMode), + Bindable = osuConfig.GetBindable(OsuSetting.ConfineMouseMode) }, new SettingsCheckbox { From ef3c8fa21f8105ec181be6392bd65c929a597f40 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 16 Aug 2020 11:38:35 +0930 Subject: [PATCH 03/62] Add tracking component to handle OsuConfineMouseMode --- osu.Game/Input/ConfineMouseTracker.cs | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 osu.Game/Input/ConfineMouseTracker.cs diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs new file mode 100644 index 0000000000..b111488a5b --- /dev/null +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -0,0 +1,72 @@ +// Copyright (c) ppy Pty Ltd . 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Input; +using osu.Game.Configuration; +using osu.Game.Screens.Play; + +namespace osu.Game.Input +{ + /// + /// Connects with + /// while providing a property for to indicate whether gameplay is currently active. + /// + public class ConfineMouseTracker : Component + { + private Bindable frameworkConfineMode; + private Bindable osuConfineMode; + + private bool gameplayActive; + + /// + /// Indicates whether osu! is currently considered "in gameplay" for the + /// purposes of . + /// + public bool GameplayActive + { + get => gameplayActive; + set + { + if (gameplayActive == value) + return; + + gameplayActive = value; + updateConfineMode(); + } + } + + [BackgroundDependencyLoader] + private void load(FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) + { + frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); + osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); + osuConfineMode.BindValueChanged(_ => updateConfineMode(), true); + } + + private void updateConfineMode() + { + switch (osuConfineMode.Value) + { + case OsuConfineMouseMode.Never: + frameworkConfineMode.Value = ConfineMouseMode.Never; + break; + + case OsuConfineMouseMode.Fullscreen: + frameworkConfineMode.Value = ConfineMouseMode.Fullscreen; + break; + + case OsuConfineMouseMode.DuringGameplay: + frameworkConfineMode.Value = GameplayActive ? ConfineMouseMode.Always : ConfineMouseMode.Never; + break; + + case OsuConfineMouseMode.Always: + frameworkConfineMode.Value = ConfineMouseMode.Always; + break; + } + } + } +} From 00f15231bc78a6e7830694bf41cbc1db331e505f Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 16 Aug 2020 21:52:39 +0930 Subject: [PATCH 04/62] Cache ConfineMouseTracker --- osu.Game/OsuGame.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 053eb01dcd..7358918758 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -88,6 +88,8 @@ namespace osu.Game private IdleTracker idleTracker; + private ConfineMouseTracker confineMouseTracker; + public readonly Bindable OverlayActivationMode = new Bindable(); protected OsuScreenStack ScreenStack; @@ -553,6 +555,7 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); + dependencies.Cache(confineMouseTracker = new ConfineMouseTracker()); AddRange(new Drawable[] { @@ -588,7 +591,8 @@ namespace osu.Game rightFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, leftFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, topMostOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, - idleTracker + idleTracker, + confineMouseTracker }); ScreenStack.ScreenPushed += screenPushed; From 85b3fff9c8a695d89453b0dbd1b55eb0d27fe5e4 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 16 Aug 2020 23:11:09 +0930 Subject: [PATCH 05/62] Update mouse confine when gameplay state changes --- osu.Game/Screens/Play/Player.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 541275cf55..3b8c4aea01 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -18,6 +18,7 @@ using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.Containers; +using osu.Game.Input; using osu.Game.IO.Archives; using osu.Game.Online.API; using osu.Game.Overlays; @@ -63,6 +64,9 @@ namespace osu.Game.Screens.Play private Bindable mouseWheelDisabled; + [Resolved(CanBeNull = true)] + private ConfineMouseTracker confineMouseTracker { get; set; } + private readonly Bindable storyboardReplacesBackground = new Bindable(); public int RestartCount; @@ -197,10 +201,15 @@ namespace osu.Game.Screens.Play skipOverlay.Hide(); } - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => + { + updatePauseOnFocusLostState(); + updateConfineMouse(); + }, true); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); + DrawableRuleset.IsPaused.ValueChanged += _ => updateConfineMouse(); DrawableRuleset.OnNewResult += r => { @@ -346,6 +355,12 @@ namespace osu.Game.Screens.Play && !DrawableRuleset.HasReplayLoaded.Value && !breakTracker.IsBreakTime.Value; + private void updateConfineMouse() + { + if (confineMouseTracker != null) + confineMouseTracker.GameplayActive = !GameplayClockContainer.IsPaused.Value && !DrawableRuleset.HasReplayLoaded.Value && !HasFailed; + } + private IBeatmap loadPlayableBeatmap() { IBeatmap playable; @@ -379,7 +394,7 @@ namespace osu.Game.Screens.Play } catch (Exception e) { - Logger.Error(e, "Could not load beatmap sucessfully!"); + Logger.Error(e, "Could not load beatmap successfully!"); //couldn't load, hard abort! return null; } From 0163688a174d84305b191caa1a2a42ce48ed3a6f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 2 Oct 2020 19:24:30 +0200 Subject: [PATCH 06/62] Remove IBeatmap from PerformanceCalculator. --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../Difficulty/CatchPerformanceCalculator.cs | 4 ++-- .../Difficulty/ManiaPerformanceCalculator.cs | 4 ++-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../Difficulty/OsuPerformanceCalculator.cs | 4 ++-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../Difficulty/TaikoPerformanceCalculator.cs | 4 ++-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs | 9 +++------ osu.Game/Rulesets/Ruleset.cs | 2 +- 10 files changed, 16 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index ca75a816f1..cb7cac436b 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Catch public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new CatchLegacySkinTransformer(source); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new CatchPerformanceCalculator(this, attributes, score); public int LegacyID => 2; diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs index a4b9ca35eb..e671e581cf 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs @@ -25,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty private int tinyTicksMissed; private int misses; - public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) - : base(ruleset, beatmap, score) + public CatchPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) + : base(ruleset, attributes, score) { } diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 91383c5548..086afb3254 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty private int countMeh; private int countMiss; - public ManiaPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) - : base(ruleset, beatmap, score) + public ManiaPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) + : base(ruleset, attributes, score) { } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 71ac85dd1b..8bf6b5e064 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new ManiaPerformanceCalculator(this, attributes, score); public const string SHORT_NAME = "mania"; diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 02577461f0..9e08163329 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty private int countMeh; private int countMiss; - public OsuPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) - : base(ruleset, beatmap, score) + public OsuPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) + : base(ruleset, attributes, score) { countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 7f4a0dcbbb..9798f15f21 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new OsuPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new OsuPerformanceCalculator(this, attributes, score); public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this); diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index c04fffa2e7..2505300425 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty private int countMeh; private int countMiss; - public TaikoPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) - : base(ruleset, beatmap, score) + public TaikoPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) + : base(ruleset, attributes, score) { } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 9d485e3f20..3bc749b868 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -153,7 +153,7 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new TaikoPerformanceCalculator(this, attributes, score); public int LegacyID => 1; diff --git a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs index ac3b817840..58427f6945 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs @@ -1,11 +1,11 @@ // 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 System.Collections.Generic; using System.Linq; using osu.Framework.Audio.Track; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; @@ -16,19 +16,16 @@ namespace osu.Game.Rulesets.Difficulty protected readonly DifficultyAttributes Attributes; protected readonly Ruleset Ruleset; - protected readonly IBeatmap Beatmap; protected readonly ScoreInfo Score; protected double TimeRate { get; private set; } = 1; - protected PerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) + protected PerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) { Ruleset = ruleset; Score = score; - Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods); - - Attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods); + Attributes = attributes ?? throw new ArgumentNullException(nameof(attributes)); ApplyMods(score.Mods); } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 915544d010..25c5f41b5b 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -158,7 +158,7 @@ namespace osu.Game.Rulesets public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); - public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => null; + public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => null; public virtual HitObjectComposer CreateHitObjectComposer() => null; From cb2f695fddf3fca6c2fd6654a25984be5b721dcf Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 2 Oct 2020 19:34:41 +0200 Subject: [PATCH 07/62] Calculate hit circle count in OsuPerformanceCalculator. --- .../Difficulty/OsuDifficultyAttributes.cs | 1 + .../Difficulty/OsuDifficultyCalculator.cs | 3 +++ .../Difficulty/OsuPerformanceCalculator.cs | 20 ++++++------------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs index a9879013f8..50f060cf06 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -11,5 +11,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty public double SpeedStrain; public double ApproachRate; public double OverallDifficulty; + public int HitCirclesCount; } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index b0d261a1cc..86c7cd2298 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -47,6 +47,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty // Add the ticks + tail of the slider. 1 is subtracted because the head circle would be counted twice (once for the slider itself in the line above) maxCombo += beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count - 1); + int hitCirclesCount = beatmap.HitObjects.Count(h => h is HitCircle); + return new OsuDifficultyAttributes { StarRating = starRating, @@ -56,6 +58,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5, OverallDifficulty = (80 - hitWindowGreat) / 6, MaxCombo = maxCombo, + HitCirclesCount = hitCirclesCount, Skills = skills }; } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 9e08163329..6acd8f9a87 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -19,9 +19,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty { public new OsuDifficultyAttributes Attributes => (OsuDifficultyAttributes)base.Attributes; - private readonly int countHitCircles; - private readonly int beatmapMaxCombo; - private Mod[] mods; private double accuracy; @@ -34,11 +31,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty public OsuPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) : base(ruleset, attributes, score) { - countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); - - beatmapMaxCombo = Beatmap.HitObjects.Count; - // Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above) - beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count - 1); } public override double Calculate(Dictionary categoryRatings = null) @@ -81,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty categoryRatings.Add("Accuracy", accuracyValue); categoryRatings.Add("OD", Attributes.OverallDifficulty); categoryRatings.Add("AR", Attributes.ApproachRate); - categoryRatings.Add("Max Combo", beatmapMaxCombo); + categoryRatings.Add("Max Combo", Attributes.MaxCombo); } return totalValue; @@ -106,8 +98,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty aimValue *= Math.Pow(0.97, countMiss); // Combo scaling - if (beatmapMaxCombo > 0) - aimValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(beatmapMaxCombo, 0.8), 1.0); + if (Attributes.MaxCombo > 0) + aimValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0); double approachRateFactor = 1.0; @@ -154,8 +146,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty speedValue *= Math.Pow(0.97, countMiss); // Combo scaling - if (beatmapMaxCombo > 0) - speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(beatmapMaxCombo, 0.8), 1.0); + if (Attributes.MaxCombo > 0) + speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0); double approachRateFactor = 1.0; if (Attributes.ApproachRate > 10.33) @@ -178,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty { // This percentage only considers HitCircles of any value - in this part of the calculation we focus on hitting the timing hit window double betterAccuracyPercentage; - int amountHitObjectsWithAccuracy = countHitCircles; + int amountHitObjectsWithAccuracy = Attributes.HitCirclesCount; if (amountHitObjectsWithAccuracy > 0) betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countOk * 2 + countMeh) / (double)(amountHitObjectsWithAccuracy * 6); From abd395a03098808ff3926be50d7063394d572342 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 2 Oct 2020 19:41:24 +0200 Subject: [PATCH 08/62] Remove unecessary using references. --- .../Difficulty/CatchPerformanceCalculator.cs | 1 - .../Difficulty/ManiaPerformanceCalculator.cs | 1 - osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 2 -- .../Difficulty/TaikoPerformanceCalculator.cs | 1 - 4 files changed, 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs index e671e581cf..6a3a16ed33 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 086afb3254..00bec18a45 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 6acd8f9a87..fed0a12536 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -5,11 +5,9 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 2505300425..2d9b95ae88 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; From d7747ebb2d5ba27bf6e5272e381dbdafc6c921bc Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 3 Oct 2020 16:51:22 +0200 Subject: [PATCH 09/62] Remove unused WorkingBeatmap argument. --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 10 +++++++++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index cb7cac436b..1f27de3352 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Catch public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new CatchLegacySkinTransformer(source); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new CatchPerformanceCalculator(this, attributes, score); + public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new CatchPerformanceCalculator(this, attributes, score); public int LegacyID => 2; diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8bf6b5e064..ecb09ebe85 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new ManiaPerformanceCalculator(this, attributes, score); + public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new ManiaPerformanceCalculator(this, attributes, score); public const string SHORT_NAME = "mania"; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 9798f15f21..cc2eebdd36 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new OsuPerformanceCalculator(this, attributes, score); + public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new OsuPerformanceCalculator(this, attributes, score); public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 3bc749b868..642eb0ddcc 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -153,7 +153,7 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => new TaikoPerformanceCalculator(this, attributes, score); + public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new TaikoPerformanceCalculator(this, attributes, score); public int LegacyID => 1; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 25c5f41b5b..2ba884efc2 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -158,7 +158,15 @@ namespace osu.Game.Rulesets public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); - public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, DifficultyAttributes attributes, ScoreInfo score) => null; + public virtual PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => null; + + [Obsolete("Use the DifficultyAttributes overload instead.")] + public PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) + { + var difficultyCalculator = CreateDifficultyCalculator(beatmap); + var difficultyAttributes = difficultyCalculator.Calculate(score.Mods); + return CreatePerformanceCalculator(difficultyAttributes, score); + } public virtual HitObjectComposer CreateHitObjectComposer() => null; From 27cc6c50467616f63daa1b1de1e43a9306bc30f1 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 3 Oct 2020 16:52:33 +0200 Subject: [PATCH 10/62] Rename HitCirclesCount -> HitCircleCount. --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs | 2 +- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 +- osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs index 50f060cf06..fff033357d 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -11,6 +11,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty public double SpeedStrain; public double ApproachRate; public double OverallDifficulty; - public int HitCirclesCount; + public int HitCircleCount; } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 86c7cd2298..6027635b75 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5, OverallDifficulty = (80 - hitWindowGreat) / 6, MaxCombo = maxCombo, - HitCirclesCount = hitCirclesCount, + HitCircleCount = hitCirclesCount, Skills = skills }; } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index fed0a12536..063cde8747 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -168,7 +168,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty { // This percentage only considers HitCircles of any value - in this part of the calculation we focus on hitting the timing hit window double betterAccuracyPercentage; - int amountHitObjectsWithAccuracy = Attributes.HitCirclesCount; + int amountHitObjectsWithAccuracy = Attributes.HitCircleCount; if (amountHitObjectsWithAccuracy > 0) betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countOk * 2 + countMeh) / (double)(amountHitObjectsWithAccuracy * 6); From 5859755886ac3e141e00e72a421bf61d19d6524e Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Mon, 5 Oct 2020 11:11:46 +1030 Subject: [PATCH 11/62] Use current OverlayActivationMode to determine confine logic --- osu.Game/Input/ConfineMouseTracker.cs | 33 +++++++++++---------------- osu.Game/Screens/Play/Player.cs | 5 ++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index b111488a5b..6565967d1d 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -7,44 +7,37 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Configuration; +using osu.Game.Overlays; using osu.Game.Screens.Play; namespace osu.Game.Input { /// - /// Connects with - /// while providing a property for to indicate whether gameplay is currently active. + /// Connects with , + /// while optionally binding an mode, usually that of the current . + /// It is assumed that while overlay activation is , we should also confine the + /// mouse cursor if it has been requested with . /// public class ConfineMouseTracker : Component { private Bindable frameworkConfineMode; private Bindable osuConfineMode; - private bool gameplayActive; - /// - /// Indicates whether osu! is currently considered "in gameplay" for the - /// purposes of . + /// The bindable used to indicate whether gameplay is active. + /// Should be bound to the corresponding bindable of the current . + /// Defaults to to assume that all other screens are considered "not gameplay". /// - public bool GameplayActive - { - get => gameplayActive; - set - { - if (gameplayActive == value) - return; - - gameplayActive = value; - updateConfineMode(); - } - } + public IBindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) { frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); - osuConfineMode.BindValueChanged(_ => updateConfineMode(), true); + osuConfineMode.ValueChanged += _ => updateConfineMode(); + + OverlayActivationMode.BindValueChanged(_ => updateConfineMode(), true); } private void updateConfineMode() @@ -60,7 +53,7 @@ namespace osu.Game.Input break; case OsuConfineMouseMode.DuringGameplay: - frameworkConfineMode.Value = GameplayActive ? ConfineMouseMode.Always : ConfineMouseMode.Never; + frameworkConfineMode.Value = OverlayActivationMode.Value == OverlayActivation.Disabled ? ConfineMouseMode.Always : ConfineMouseMode.Never; break; case OsuConfineMouseMode.Always: diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 77f873083a..6d2f61bdf1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -229,6 +229,8 @@ namespace osu.Game.Screens.Play DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); + confineMouseTracker.OverlayActivationMode.BindTo(OverlayActivationMode); + // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); @@ -365,9 +367,6 @@ namespace osu.Game.Screens.Play OverlayActivationMode.Value = OverlayActivation.UserTriggered; else OverlayActivationMode.Value = OverlayActivation.Disabled; - - if (confineMouseTracker != null) - confineMouseTracker.GameplayActive = !GameplayClockContainer.IsPaused.Value && !DrawableRuleset.HasReplayLoaded.Value && !HasFailed; } private void updatePauseOnFocusLostState() => From a483dfd2d7157131d886d8b7c92a4b08defdbf63 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Mon, 5 Oct 2020 11:54:39 +1030 Subject: [PATCH 12/62] Allow confineMouseTracker to be null --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 6d2f61bdf1..de67b2d46d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -229,7 +229,7 @@ namespace osu.Game.Screens.Play DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); - confineMouseTracker.OverlayActivationMode.BindTo(OverlayActivationMode); + confineMouseTracker?.OverlayActivationMode.BindTo(OverlayActivationMode); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); From 46f6e84a3351dd77e4de78f785670788ab92a908 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 12:33:57 +0900 Subject: [PATCH 13/62] Fix disclaimer potentially running same code from two different threads --- osu.Game/Screens/Menu/Disclaimer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index fcb9aacd76..8368047d5a 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -42,8 +42,11 @@ namespace osu.Game.Screens.Menu ValidForResume = false; } + [Resolved] + private IAPIProvider api { get; set; } + [BackgroundDependencyLoader] - private void load(OsuColour colours, IAPIProvider api) + private void load(OsuColour colours) { InternalChildren = new Drawable[] { @@ -104,7 +107,9 @@ namespace osu.Game.Screens.Menu iconColour = colours.Yellow; - currentUser.BindTo(api.LocalUser); + // manually transfer the user once, but only do the final bind in LoadComplete to avoid thread woes (API scheduler could run while this screen is still loading). + // the manual transfer is here to ensure all text content is loaded ahead of time as this is very early in the game load process and we want to avoid stutters. + currentUser.Value = api.LocalUser.Value; currentUser.BindValueChanged(e => { supportFlow.Children.ForEach(d => d.FadeOut().Expire()); @@ -141,6 +146,8 @@ namespace osu.Game.Screens.Menu base.LoadComplete(); if (nextScreen != null) LoadComponentAsync(nextScreen); + + currentUser.BindTo(api.LocalUser); } public override void OnEntering(IScreen last) From 5e10ac418bb188044f990d0b96c6544f16eff26b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 13:09:42 +0900 Subject: [PATCH 14/62] Add update notifications for iOS builds --- osu.Game/Updater/SimpleUpdateManager.cs | 5 +++++ osu.iOS/OsuGameIOS.cs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/osu.Game/Updater/SimpleUpdateManager.cs b/osu.Game/Updater/SimpleUpdateManager.cs index ebb9995c66..48c6722bd9 100644 --- a/osu.Game/Updater/SimpleUpdateManager.cs +++ b/osu.Game/Updater/SimpleUpdateManager.cs @@ -79,6 +79,11 @@ namespace osu.Game.Updater bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".AppImage")); break; + case RuntimeInfo.Platform.iOS: + // iOS releases are available via testflight. this link seems to work well enough for now. + // see https://stackoverflow.com/a/32960501 + return "itms-beta://beta.itunes.apple.com/v1/app/1447765923"; + case RuntimeInfo.Platform.Android: // on our testing device this causes the download to magically disappear. //bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".apk")); diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index 3a16f81530..5125ad81e0 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -11,5 +11,7 @@ namespace osu.iOS public class OsuGameIOS : OsuGame { public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString()); + + protected override UpdateManager CreateUpdateManager() => new SimpleUpdateManager(); } } From 767a2a10bd0f0798eb5b313068c5b43b3f962160 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 13:56:38 +0900 Subject: [PATCH 15/62] Fix incorrect sliderendcircle fallback logic Correctly handle the case where a skin has "sliderendcircle.png" but not "sliderendcircleoverlay.png". --- .../Skinning/LegacyMainCirclePiece.cs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index f051cbfa3b..d556ecb9bc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -49,6 +49,25 @@ namespace osu.Game.Rulesets.Osu.Skinning { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; + Texture baseTexture; + Texture overlayTexture; + bool allowFallback = false; + + // attempt lookup using priority specification + 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). + overlayTexture = getTextureWithFallback("overlay"); + InternalChildren = new Drawable[] { circleSprites = new Container @@ -60,13 +79,13 @@ namespace osu.Game.Rulesets.Osu.Skinning { hitCircleSprite = new Sprite { - Texture = getTextureWithFallback(string.Empty), + Texture = baseTexture, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, hitCircleOverlay = new Sprite { - Texture = getTextureWithFallback("overlay"), + Texture = overlayTexture, Anchor = Anchor.Centre, Origin = Anchor.Centre, } @@ -101,8 +120,13 @@ namespace osu.Game.Rulesets.Osu.Skinning Texture tex = null; if (!string.IsNullOrEmpty(priorityLookup)) + { tex = skin.GetTexture($"{priorityLookup}{name}"); + if (!allowFallback) + return tex; + } + return tex ?? skin.GetTexture($"hitcircle{name}"); } } From ed982e8dd13f9f4657e1463a7bd19a7aac2f41f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 14:08:55 +0900 Subject: [PATCH 16/62] Make stacked hitcircles more visible when using default skin --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs index bcf64b81a6..619fea73bc 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Origin = Anchor.Centre; Masking = true; - BorderThickness = 10; + BorderThickness = 9; // roughly matches slider borders and makes stacked circles distinctly visible from each other. BorderColour = Color4.White; Child = new Box From 048507478ee199fc155be842a5d008a05dcf1869 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 14:12:46 +0900 Subject: [PATCH 17/62] Join declaration and specification --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index d556ecb9bc..382d6e53cc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -49,12 +49,10 @@ namespace osu.Game.Rulesets.Osu.Skinning { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; - Texture baseTexture; - Texture overlayTexture; bool allowFallback = false; // attempt lookup using priority specification - baseTexture = getTextureWithFallback(string.Empty); + 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) @@ -66,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.Skinning // 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). - overlayTexture = getTextureWithFallback("overlay"); + Texture overlayTexture = getTextureWithFallback("overlay"); InternalChildren = new Drawable[] { From 9d7880afdaebdc2f929c5a04f0ce674cfdab8706 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:18:41 +0900 Subject: [PATCH 18/62] Make SettingsItem conform to IHasCurrentValue --- .../ManiaSettingsSubsection.cs | 4 ++-- .../UI/OsuSettingsSubsection.cs | 6 ++--- osu.Game.Tournament/Components/DateTextBox.cs | 18 +++++++------- .../Screens/Editors/RoundEditorScreen.cs | 12 +++++----- .../Screens/Editors/SeedingEditorScreen.cs | 10 ++++---- .../Screens/Editors/TeamEditorScreen.cs | 12 +++++----- .../Screens/Gameplay/GameplayScreen.cs | 4 ++-- .../Ladder/Components/LadderEditorSettings.cs | 12 +++++----- .../Screens/TeamIntro/SeedingScreen.cs | 2 +- .../Configuration/SettingSourceAttribute.cs | 12 +++++----- .../Sections/Audio/AudioDevicesSettings.cs | 2 +- .../Sections/Audio/MainMenuSettings.cs | 8 +++---- .../Settings/Sections/Audio/OffsetSettings.cs | 2 +- .../Settings/Sections/Audio/VolumeSettings.cs | 8 +++---- .../Sections/Debug/GeneralSettings.cs | 4 ++-- .../Sections/Gameplay/GeneralSettings.cs | 24 +++++++++---------- .../Sections/Gameplay/ModsSettings.cs | 2 +- .../Sections/Gameplay/SongSelectSettings.cs | 10 ++++---- .../Sections/General/LanguageSettings.cs | 2 +- .../Sections/General/LoginSettings.cs | 4 ++-- .../Sections/General/UpdateSettings.cs | 2 +- .../Sections/Graphics/DetailSettings.cs | 8 +++---- .../Sections/Graphics/LayoutSettings.cs | 20 ++++++++-------- .../Sections/Graphics/RendererSettings.cs | 6 ++--- .../Graphics/UserInterfaceSettings.cs | 6 ++--- .../Settings/Sections/Input/MouseSettings.cs | 12 +++++----- .../Settings/Sections/Online/WebSettings.cs | 4 ++-- .../Overlays/Settings/Sections/SkinSection.cs | 12 +++++----- osu.Game/Overlays/Settings/SettingsItem.cs | 4 ++-- .../Edit/Timing/SliderWithTextBoxInput.cs | 8 +++---- osu.Game/Screens/Edit/Timing/TimingSection.cs | 14 +++++------ .../Play/PlayerSettings/PlaybackSettings.cs | 4 ++-- .../Play/PlayerSettings/VisualSettings.cs | 4 ++-- 33 files changed, 131 insertions(+), 131 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index b470405df2..de77af8306 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Mania new SettingsEnumDropdown { LabelText = "Scrolling direction", - Bindable = config.GetBindable(ManiaRulesetSetting.ScrollDirection) + Current = config.GetBindable(ManiaRulesetSetting.ScrollDirection) }, new SettingsSlider { LabelText = "Scroll speed", - Bindable = config.GetBindable(ManiaRulesetSetting.ScrollTime), + Current = config.GetBindable(ManiaRulesetSetting.ScrollTime), KeyboardStep = 5 }, }; diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 88adf72551..3870f303b4 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -27,17 +27,17 @@ namespace osu.Game.Rulesets.Osu.UI new SettingsCheckbox { LabelText = "Snaking in sliders", - Bindable = config.GetBindable(OsuRulesetSetting.SnakingInSliders) + Current = config.GetBindable(OsuRulesetSetting.SnakingInSliders) }, new SettingsCheckbox { LabelText = "Snaking out sliders", - Bindable = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) + Current = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) }, new SettingsCheckbox { LabelText = "Cursor trail", - Bindable = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) + Current = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, }; } diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs index a1b5ac38ea..5782301a65 100644 --- a/osu.Game.Tournament/Components/DateTextBox.cs +++ b/osu.Game.Tournament/Components/DateTextBox.cs @@ -10,34 +10,34 @@ namespace osu.Game.Tournament.Components { public class DateTextBox : SettingsTextBox { - public new Bindable Bindable + public new Bindable Current { - get => bindable; + get => current; set { - bindable = value.GetBoundCopy(); - bindable.BindValueChanged(dto => - base.Bindable.Value = dto.NewValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"), true); + current = value.GetBoundCopy(); + current.BindValueChanged(dto => + 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. - private Bindable bindable = new Bindable(); + private Bindable current = new Bindable(); public DateTextBox() { - base.Bindable = new Bindable(); + base.Current = new Bindable(); ((OsuTextBox)Control).OnCommit += (sender, newText) => { try { - bindable.Value = DateTimeOffset.Parse(sender.Text); + current.Value = DateTimeOffset.Parse(sender.Text); } catch { // reset textbox content to its last valid state on a parse failure. - bindable.TriggerChange(); + current.TriggerChange(); } }; } diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 8b8078e119..069ddfa4db 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -63,25 +63,25 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Name", Width = 0.33f, - Bindable = Model.Name + Current = Model.Name }, new SettingsTextBox { LabelText = "Description", Width = 0.33f, - Bindable = Model.Description + Current = Model.Description }, new DateTextBox { LabelText = "Start Time", Width = 0.33f, - Bindable = Model.StartDate + Current = Model.StartDate }, new SettingsSlider { LabelText = "Best of", Width = 0.33f, - Bindable = Model.BestOf + Current = Model.BestOf }, new SettingsButton { @@ -186,14 +186,14 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "Beatmap ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmapId, + Current = beatmapId, }, new SettingsTextBox { LabelText = "Mods", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = mods, + Current = mods, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs index 0973a7dc75..7bd8d3f6a0 100644 --- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs @@ -74,13 +74,13 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Mod", Width = 0.33f, - Bindable = Model.Mod + Current = Model.Mod }, new SettingsSlider { LabelText = "Seed", Width = 0.33f, - Bindable = Model.Seed + Current = Model.Seed }, new SettingsButton { @@ -187,21 +187,21 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "Beatmap ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmapId, + Current = beatmapId, }, new SettingsSlider { LabelText = "Seed", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmap.Seed + Current = beatmap.Seed }, new SettingsTextBox { LabelText = "Score", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = score, + Current = score, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index dbfcfe4225..7196f47bd6 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -102,31 +102,31 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Name", Width = 0.2f, - Bindable = Model.FullName + Current = Model.FullName }, new SettingsTextBox { LabelText = "Acronym", Width = 0.2f, - Bindable = Model.Acronym + Current = Model.Acronym }, new SettingsTextBox { LabelText = "Flag", Width = 0.2f, - Bindable = Model.FlagName + Current = Model.FlagName }, new SettingsTextBox { LabelText = "Seed", Width = 0.2f, - Bindable = Model.Seed + Current = Model.Seed }, new SettingsSlider { LabelText = "Last Year Placement", Width = 0.33f, - Bindable = Model.LastYearPlacing + Current = Model.LastYearPlacing }, new SettingsButton { @@ -247,7 +247,7 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "User ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = userId, + Current = userId, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index e4e3842369..e4ec45c00e 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -113,13 +113,13 @@ namespace osu.Game.Tournament.Screens.Gameplay new SettingsSlider { LabelText = "Chroma width", - Bindable = LadderInfo.ChromaKeyWidth, + Current = LadderInfo.ChromaKeyWidth, KeyboardStep = 1, }, new SettingsSlider { LabelText = "Players per team", - Bindable = LadderInfo.PlayersPerTeam, + Current = LadderInfo.PlayersPerTeam, KeyboardStep = 1, } } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index b60eb814e5..cf4466a2e3 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -51,15 +51,15 @@ namespace osu.Game.Tournament.Screens.Ladder.Components editorInfo.Selected.ValueChanged += selection => { - roundDropdown.Bindable = selection.NewValue?.Round; + roundDropdown.Current = selection.NewValue?.Round; losersCheckbox.Current = selection.NewValue?.Losers; - dateTimeBox.Bindable = selection.NewValue?.Date; + dateTimeBox.Current = selection.NewValue?.Date; - team1Dropdown.Bindable = selection.NewValue?.Team1; - team2Dropdown.Bindable = selection.NewValue?.Team2; + team1Dropdown.Current = selection.NewValue?.Team1; + team2Dropdown.Current = selection.NewValue?.Team2; }; - roundDropdown.Bindable.ValueChanged += round => + roundDropdown.Current.ValueChanged += round => { if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value) { @@ -88,7 +88,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { public SettingsRoundDropdown(BindableList rounds) { - Bindable = new Bindable(); + Current = new Bindable(); foreach (var r in rounds.Prepend(new TournamentRound())) add(r); diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index eed3cac9f0..b343608e69 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro new SettingsTeamDropdown(LadderInfo.Teams) { LabelText = "Show specific team", - Bindable = currentTeam, + Current = currentTeam, } } } diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index fe487cb1d0..50069be4b2 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -57,7 +57,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber, + Current = bNumber, KeyboardStep = 0.1f, }; @@ -67,7 +67,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber, + Current = bNumber, KeyboardStep = 0.1f, }; @@ -77,7 +77,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber + Current = bNumber }; break; @@ -86,7 +86,7 @@ namespace osu.Game.Configuration yield return new SettingsCheckbox { LabelText = attr.Label, - Bindable = bBool + Current = bBool }; break; @@ -95,7 +95,7 @@ namespace osu.Game.Configuration yield return new SettingsTextBox { LabelText = attr.Label, - Bindable = bString + Current = bString }; break; @@ -105,7 +105,7 @@ namespace osu.Game.Configuration var dropdown = (Drawable)Activator.CreateInstance(dropdownType); dropdownType.GetProperty(nameof(SettingsDropdown.LabelText))?.SetValue(dropdown, attr.Label); - dropdownType.GetProperty(nameof(SettingsDropdown.Bindable))?.SetValue(dropdown, bindable); + dropdownType.GetProperty(nameof(SettingsDropdown.Current))?.SetValue(dropdown, bindable); yield return dropdown; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 3da64e0de4..bed74542c9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio updateItems(); - dropdown.Bindable = audio.AudioDevice; + dropdown.Current = audio.AudioDevice; audio.OnNewDevice += onDeviceChanged; audio.OnLostDevice += onDeviceChanged; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs index a303f93b34..d5de32ed05 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs @@ -21,23 +21,23 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsCheckbox { LabelText = "Interface voices", - Bindable = config.GetBindable(OsuSetting.MenuVoice) + Current = config.GetBindable(OsuSetting.MenuVoice) }, new SettingsCheckbox { LabelText = "osu! music theme", - Bindable = config.GetBindable(OsuSetting.MenuMusic) + Current = config.GetBindable(OsuSetting.MenuMusic) }, new SettingsDropdown { LabelText = "Intro sequence", - Bindable = config.GetBindable(OsuSetting.IntroSequence), + Current = config.GetBindable(OsuSetting.IntroSequence), Items = Enum.GetValues(typeof(IntroSequence)).Cast() }, new SettingsDropdown { LabelText = "Background source", - Bindable = config.GetBindable(OsuSetting.MenuBackgroundSource), + Current = config.GetBindable(OsuSetting.MenuBackgroundSource), Items = Enum.GetValues(typeof(BackgroundSource)).Cast() } }; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs index aaa4302553..c9a81b955b 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsSlider { LabelText = "Audio offset", - Bindable = config.GetBindable(OsuSetting.AudioOffset), + Current = config.GetBindable(OsuSetting.AudioOffset), KeyboardStep = 1f }, new SettingsButton diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index bda677ecd6..c172a76ab9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -20,28 +20,28 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsSlider { LabelText = "Master", - Bindable = audio.Volume, + Current = audio.Volume, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Master (window inactive)", - Bindable = config.GetBindable(OsuSetting.VolumeInactive), + Current = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Effect", - Bindable = audio.VolumeSample, + Current = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Music", - Bindable = audio.VolumeTrack, + Current = audio.VolumeTrack, KeyboardStep = 0.01f, DisplayAsPercentage = true }, diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs index 9edb18e065..f05b876d8f 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs @@ -19,12 +19,12 @@ namespace osu.Game.Overlays.Settings.Sections.Debug new SettingsCheckbox { LabelText = "Show log overlay", - Bindable = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) + Current = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) }, new SettingsCheckbox { LabelText = "Bypass front-to-back render pass", - Bindable = config.GetBindable(DebugSetting.BypassFrontToBackPass) + Current = config.GetBindable(DebugSetting.BypassFrontToBackPass) } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 0149e6c3a6..73968761e2 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -21,62 +21,62 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsSlider { LabelText = "Background dim", - Bindable = config.GetBindable(OsuSetting.DimLevel), + Current = config.GetBindable(OsuSetting.DimLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Background blur", - Bindable = config.GetBindable(OsuSetting.BlurLevel), + Current = config.GetBindable(OsuSetting.BlurLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsCheckbox { LabelText = "Lighten playfield during breaks", - Bindable = config.GetBindable(OsuSetting.LightenDuringBreaks) + Current = config.GetBindable(OsuSetting.LightenDuringBreaks) }, new SettingsCheckbox { LabelText = "Show score overlay", - Bindable = config.GetBindable(OsuSetting.ShowInterface) + Current = config.GetBindable(OsuSetting.ShowInterface) }, new SettingsCheckbox { LabelText = "Show difficulty graph on progress bar", - Bindable = config.GetBindable(OsuSetting.ShowProgressGraph) + Current = config.GetBindable(OsuSetting.ShowProgressGraph) }, new SettingsCheckbox { LabelText = "Show health display even when you can't fail", - Bindable = config.GetBindable(OsuSetting.ShowHealthDisplayWhenCantFail), + Current = config.GetBindable(OsuSetting.ShowHealthDisplayWhenCantFail), Keywords = new[] { "hp", "bar" } }, new SettingsCheckbox { LabelText = "Fade playfield to red when health is low", - Bindable = config.GetBindable(OsuSetting.FadePlayfieldWhenHealthLow), + Current = config.GetBindable(OsuSetting.FadePlayfieldWhenHealthLow), }, new SettingsCheckbox { LabelText = "Always show key overlay", - Bindable = config.GetBindable(OsuSetting.KeyOverlay) + Current = config.GetBindable(OsuSetting.KeyOverlay) }, new SettingsCheckbox { LabelText = "Positional hitsounds", - Bindable = config.GetBindable(OsuSetting.PositionalHitSounds) + Current = config.GetBindable(OsuSetting.PositionalHitSounds) }, new SettingsEnumDropdown { LabelText = "Score meter type", - Bindable = config.GetBindable(OsuSetting.ScoreMeter) + Current = config.GetBindable(OsuSetting.ScoreMeter) }, new SettingsEnumDropdown { LabelText = "Score display mode", - Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + Current = config.GetBindable(OsuSetting.ScoreDisplayMode) } }; @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay Add(new SettingsCheckbox { LabelText = "Disable Windows key during gameplay", - Bindable = config.GetBindable(OsuSetting.GameplayDisableWinKey) + Current = config.GetBindable(OsuSetting.GameplayDisableWinKey) }); } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs index 0babb98066..2b2fb9cef7 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsCheckbox { LabelText = "Increase visibility of first object when visual impairment mods are enabled", - Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), + Current = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index 0c42247993..b26876556e 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -31,31 +31,31 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsCheckbox { LabelText = "Right mouse drag to absolute scroll", - Bindable = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), + Current = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), }, new SettingsCheckbox { LabelText = "Show converted beatmaps", - Bindable = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), + Current = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), }, new SettingsSlider { LabelText = "Display beatmaps from", - Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum), + Current = config.GetBindable(OsuSetting.DisplayStarsMinimum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsSlider { LabelText = "up to", - Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum), + Current = config.GetBindable(OsuSetting.DisplayStarsMaximum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsEnumDropdown { LabelText = "Random selection algorithm", - Bindable = config.GetBindable(OsuSetting.RandomSelectAlgorithm), + Current = config.GetBindable(OsuSetting.RandomSelectAlgorithm), } }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index 236bfbecc3..44e42ecbfe 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.General new SettingsCheckbox { LabelText = "Prefer metadata in original language", - Bindable = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) + Current = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index f96e204f62..9e358d0cf5 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -240,12 +240,12 @@ namespace osu.Game.Overlays.Settings.Sections.General new SettingsCheckbox { LabelText = "Remember username", - Bindable = config.GetBindable(OsuSetting.SaveUsername), + Current = config.GetBindable(OsuSetting.SaveUsername), }, new SettingsCheckbox { LabelText = "Stay signed in", - Bindable = config.GetBindable(OsuSetting.SavePassword), + Current = config.GetBindable(OsuSetting.SavePassword), }, new Container { diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 9c7d0b0be4..a59a6b00b9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Add(new SettingsEnumDropdown { LabelText = "Release stream", - Bindable = config.GetBindable(OsuSetting.ReleaseStream), + Current = config.GetBindable(OsuSetting.ReleaseStream), }); if (updateManager?.CanCheckForUpdate == true) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index 3089040f96..30caa45995 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -19,22 +19,22 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsCheckbox { LabelText = "Storyboard / Video", - Bindable = config.GetBindable(OsuSetting.ShowStoryboard) + Current = config.GetBindable(OsuSetting.ShowStoryboard) }, new SettingsCheckbox { LabelText = "Hit Lighting", - Bindable = config.GetBindable(OsuSetting.HitLighting) + Current = config.GetBindable(OsuSetting.HitLighting) }, new SettingsEnumDropdown { LabelText = "Screenshot format", - Bindable = config.GetBindable(OsuSetting.ScreenshotFormat) + Current = config.GetBindable(OsuSetting.ScreenshotFormat) }, new SettingsCheckbox { LabelText = "Show menu cursor in screenshots", - Bindable = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) + Current = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 4312b319c0..14b8dbfac0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics windowModeDropdown = new SettingsDropdown { LabelText = "Screen mode", - Bindable = config.GetBindable(FrameworkSetting.WindowMode), + Current = config.GetBindable(FrameworkSetting.WindowMode), ItemSource = windowModes, }, resolutionSettingsContainer = new Container @@ -74,14 +74,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = "UI Scaling", TransferValueOnCommit = true, - Bindable = osuConfig.GetBindable(OsuSetting.UIScale), + Current = osuConfig.GetBindable(OsuSetting.UIScale), KeyboardStep = 0.01f, Keywords = new[] { "scale", "letterbox" }, }, new SettingsEnumDropdown { LabelText = "Screen Scaling", - Bindable = osuConfig.GetBindable(OsuSetting.Scaling), + Current = osuConfig.GetBindable(OsuSetting.Scaling), Keywords = new[] { "scale", "letterbox" }, }, scalingSettings = new FillFlowContainer> @@ -97,28 +97,28 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsSlider { LabelText = "Horizontal position", - Bindable = scalingPositionX, + Current = scalingPositionX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical position", - Bindable = scalingPositionY, + Current = scalingPositionY, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Horizontal scale", - Bindable = scalingSizeX, + Current = scalingSizeX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical scale", - Bindable = scalingSizeY, + Current = scalingSizeY, KeyboardStep = 0.01f, 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(); @@ -137,10 +137,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics LabelText = "Resolution", ShowsDefaultIndicator = false, Items = resolutions, - Bindable = sizeFullscreen + Current = sizeFullscreen }; - windowModeDropdown.Bindable.BindValueChanged(mode => + windowModeDropdown.Current.BindValueChanged(mode => { if (mode.NewValue == WindowMode.Fullscreen) { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 69ff9b43e5..8773e6763c 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -23,17 +23,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsEnumDropdown { LabelText = "Frame limiter", - Bindable = config.GetBindable(FrameworkSetting.FrameSync) + Current = config.GetBindable(FrameworkSetting.FrameSync) }, new SettingsEnumDropdown { LabelText = "Threading mode", - Bindable = config.GetBindable(FrameworkSetting.ExecutionMode) + Current = config.GetBindable(FrameworkSetting.ExecutionMode) }, new SettingsCheckbox { LabelText = "Show FPS", - Bindable = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) + Current = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs index a8953ac3a2..38c30ddd64 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs @@ -20,17 +20,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsCheckbox { LabelText = "Rotate cursor when dragging", - Bindable = config.GetBindable(OsuSetting.CursorRotation) + Current = config.GetBindable(OsuSetting.CursorRotation) }, new SettingsCheckbox { LabelText = "Parallax", - Bindable = config.GetBindable(OsuSetting.MenuParallax) + Current = config.GetBindable(OsuSetting.MenuParallax) }, new SettingsSlider { LabelText = "Hold-to-confirm activation time", - Bindable = config.GetBindable(OsuSetting.UIHoldActivationDelay), + Current = config.GetBindable(OsuSetting.UIHoldActivationDelay), KeyboardStep = 50 }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index d27ab63fb7..5227e328ec 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -35,32 +35,32 @@ namespace osu.Game.Overlays.Settings.Sections.Input new SettingsCheckbox { LabelText = "Raw input", - Bindable = rawInputToggle + Current = rawInputToggle }, new SensitivitySetting { LabelText = "Cursor sensitivity", - Bindable = sensitivityBindable + Current = sensitivityBindable }, new SettingsCheckbox { LabelText = "Map absolute input to window", - Bindable = config.GetBindable(FrameworkSetting.MapAbsoluteInputToWindow) + Current = config.GetBindable(FrameworkSetting.MapAbsoluteInputToWindow) }, new SettingsEnumDropdown { LabelText = "Confine mouse cursor to window", - Bindable = config.GetBindable(FrameworkSetting.ConfineMouseMode), + Current = config.GetBindable(FrameworkSetting.ConfineMouseMode), }, new SettingsCheckbox { LabelText = "Disable mouse wheel during gameplay", - Bindable = osuConfig.GetBindable(OsuSetting.MouseDisableWheel) + Current = osuConfig.GetBindable(OsuSetting.MouseDisableWheel) }, new SettingsCheckbox { LabelText = "Disable mouse buttons during gameplay", - Bindable = osuConfig.GetBindable(OsuSetting.MouseDisableButtons) + Current = osuConfig.GetBindable(OsuSetting.MouseDisableButtons) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 23513eade8..6461bd7b93 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -19,13 +19,13 @@ namespace osu.Game.Overlays.Settings.Sections.Online new SettingsCheckbox { LabelText = "Warn about opening external links", - Bindable = config.GetBindable(OsuSetting.ExternalLinkWarning) + Current = config.GetBindable(OsuSetting.ExternalLinkWarning) }, new SettingsCheckbox { LabelText = "Prefer downloads without video", Keywords = new[] { "no-video" }, - Bindable = config.GetBindable(OsuSetting.PreferNoVideo) + Current = config.GetBindable(OsuSetting.PreferNoVideo) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 596d3a9801..1ade4befdc 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -47,29 +47,29 @@ namespace osu.Game.Overlays.Settings.Sections new SettingsSlider { LabelText = "Menu cursor size", - Bindable = config.GetBindable(OsuSetting.MenuCursorSize), + Current = config.GetBindable(OsuSetting.MenuCursorSize), KeyboardStep = 0.01f }, new SettingsSlider { LabelText = "Gameplay cursor size", - Bindable = config.GetBindable(OsuSetting.GameplayCursorSize), + Current = config.GetBindable(OsuSetting.GameplayCursorSize), KeyboardStep = 0.01f }, new SettingsCheckbox { LabelText = "Adjust gameplay cursor size based on current beatmap", - Bindable = config.GetBindable(OsuSetting.AutoCursorSize) + Current = config.GetBindable(OsuSetting.AutoCursorSize) }, new SettingsCheckbox { LabelText = "Beatmap skins", - Bindable = config.GetBindable(OsuSetting.BeatmapSkins) + Current = config.GetBindable(OsuSetting.BeatmapSkins) }, new SettingsCheckbox { LabelText = "Beatmap hitsounds", - Bindable = config.GetBindable(OsuSetting.BeatmapHitsounds) + Current = config.GetBindable(OsuSetting.BeatmapHitsounds) }, }; @@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Settings.Sections config.BindWith(OsuSetting.Skin, configBindable); - skinDropdown.Bindable = dropdownBindable; + skinDropdown.Current = dropdownBindable; skinDropdown.Items = skins.GetAllUsableSkins().ToArray(); // Todo: This should not be necessary when OsuConfigManager is databased diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index c2dd40d2a6..ad6aaafd9d 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract class SettingsItem : Container, IFilterable, ISettingsItem + public abstract class SettingsItem : Container, IFilterable, ISettingsItem, IHasCurrentValue { protected abstract Drawable CreateControl(); @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Settings } } - public virtual Bindable Bindable + public virtual Bindable Current { get => controlWithCurrent.Current; set => controlWithCurrent.Current = value; diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index d5afc8978d..f2f9f76143 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Edit.Timing { - internal class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue + public class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue where T : struct, IEquatable, IComparable, IConvertible { private readonly SettingsSlider slider; @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Timing try { - slider.Bindable.Parse(t.Text); + slider.Current.Parse(t.Text); } catch { @@ -71,8 +71,8 @@ namespace osu.Game.Screens.Edit.Timing public Bindable Current { - get => slider.Bindable; - set => slider.Bindable = value; + get => slider.Current; + set => slider.Current = value; } } } diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 2ab8703cc4..1ae2a86885 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -36,14 +36,14 @@ namespace osu.Game.Screens.Edit.Timing { if (point.NewValue != null) { - bpmSlider.Bindable = point.NewValue.BeatLengthBindable; - bpmSlider.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); + bpmSlider.Current = point.NewValue.BeatLengthBindable; + bpmSlider.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable; // no need to hook change handler here as it's the same bindable as above - timeSignature.Bindable = point.NewValue.TimeSignatureBindable; - timeSignature.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); + timeSignature.Current = point.NewValue.TimeSignatureBindable; + timeSignature.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); } } @@ -121,14 +121,14 @@ namespace osu.Game.Screens.Edit.Timing beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true); bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); - base.Bindable = bpmBindable; + base.Current = bpmBindable; TransferValueOnCommit = true; } - public override Bindable Bindable + public override Bindable Current { - get => base.Bindable; + get => base.Current; set { // incoming will be beat length, not bpm diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 24ddc277cd..16e29ac3c8 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -51,14 +51,14 @@ namespace osu.Game.Screens.Play.PlayerSettings } }, }, - rateSlider = new PlayerSliderBar { Bindable = UserPlaybackRate } + rateSlider = new PlayerSliderBar { Current = UserPlaybackRate } }; } protected override void 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); } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e06cf5c6d5..8f29fe7893 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -50,8 +50,8 @@ namespace osu.Game.Screens.Play.PlayerSettings [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - dimSliderBar.Bindable = config.GetBindable(OsuSetting.DimLevel); - blurSliderBar.Bindable = config.GetBindable(OsuSetting.BlurLevel); + dimSliderBar.Current = config.GetBindable(OsuSetting.DimLevel); + blurSliderBar.Current = config.GetBindable(OsuSetting.BlurLevel); showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapHitsoundsToggle.Current = config.GetBindable(OsuSetting.BeatmapHitsounds); From 28756d862b630eb5b28eecf8c9373dfca97be24b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 14:22:53 +0900 Subject: [PATCH 19/62] Add placeholder text/colour when no beatmap background is specified yet --- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 3d94737e59..1e9ebec41d 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -59,8 +59,11 @@ namespace osu.Game.Screens.Edit.Setup { } + [Resolved] + private OsuColour colours { get; set; } + [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { Container audioTrackFileChooserContainer = new Container { @@ -187,7 +190,27 @@ namespace osu.Game.Screens.Edit.Setup FillMode = FillMode.Fill, }, background => { - backgroundSpriteContainer.Child = 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); }); } From 87bf3bdc161a601893e25ab7899ab2151952e39f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 16:40:47 +0900 Subject: [PATCH 20/62] Add the most basic implementation of LabelledSliderBar feasible --- .../TestSceneLabelledSliderBar.cs | 46 +++++++++++++++++++ .../UserInterfaceV2/LabelledSliderBar.cs | 24 ++++++++++ 2 files changed, 70 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs create mode 100644 osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs new file mode 100644 index 0000000000..393420e700 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . 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 component; + + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500, + AutoSizeAxes = Axes.Y, + Child = component = new LabelledSliderBar + { + 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; + }); + } + } +} diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs new file mode 100644 index 0000000000..cba94e314b --- /dev/null +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs @@ -0,0 +1,24 @@ +// 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.Graphics; +using osu.Game.Overlays.Settings; + +namespace osu.Game.Graphics.UserInterfaceV2 +{ + public class LabelledSliderBar : LabelledComponent, TNumber> + where TNumber : struct, IEquatable, IComparable, IConvertible + { + public LabelledSliderBar() + : base(true) + { + } + + protected override SettingsSlider CreateComponent() => new SettingsSlider + { + TransferValueOnCommit = true, + RelativeSizeAxes = Axes.X, + }; + } +} From 98fe5f78ee956d3765324a1d8482fb1945a63673 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 15:17:15 +0900 Subject: [PATCH 21/62] Split setup screen up into sections (and use a SectionContainer) --- .../Editing/TestSceneEditorBeatmapCreation.cs | 2 +- .../Edit/Setup/FileChooserLabelledTextBox.cs | 73 ++++ .../Screens/Edit/Setup/MetadataSection.cs | 71 ++++ .../Screens/Edit/Setup/ResourcesSection.cs | 211 ++++++++++++ osu.Game/Screens/Edit/Setup/SetupScreen.cs | 319 +----------------- osu.Game/Screens/Edit/Setup/SetupSection.cs | 43 +++ 6 files changed, 417 insertions(+), 302 deletions(-) create mode 100644 osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs create mode 100644 osu.Game/Screens/Edit/Setup/MetadataSection.cs create mode 100644 osu.Game/Screens/Edit/Setup/ResourcesSection.cs create mode 100644 osu.Game/Screens/Edit/Setup/SetupSection.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index 13a3195824..7584c74c71 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual.Editing using (var zip = ZipArchive.Open(temp)) zip.WriteToDirectory(extractedFolder); - bool success = setup.ChangeAudioTrack(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3")); + bool success = setup.ChildrenOfType().First().ChangeAudioTrack(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3")); File.Delete(temp); Directory.Delete(extractedFolder, true); diff --git a/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs b/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs new file mode 100644 index 0000000000..b802b3405a --- /dev/null +++ b/osu.Game/Screens/Edit/Setup/FileChooserLabelledTextBox.cs @@ -0,0 +1,73 @@ +// 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 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 +{ + /// + /// A labelled textbox which reveals an inline file chooser when clicked. + /// + internal class FileChooserLabelledTextBox : LabelledTextBox + { + public Container Target; + + private readonly IBindable currentFile = new Bindable(); + + public FileChooserLabelledTextBox() + { + currentFile.BindValueChanged(onFileSelected); + } + + private void onFileSelected(ValueChangedEvent 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); + } + } + } +} diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs new file mode 100644 index 0000000000..31a2c2ce1a --- /dev/null +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -0,0 +1,71 @@ +// Copyright (c) ppy Pty Ltd . 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() + { + Flow.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 Flow.OfType()) + 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; + } + } +} diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs new file mode 100644 index 0000000000..86d7968856 --- /dev/null +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -0,0 +1,211 @@ +// Copyright (c) ppy Pty Ltd . 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 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, + }; + + Flow.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 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); + }); + } + } +} diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 1e9ebec41d..cd4f6733c0 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -1,76 +1,33 @@ // 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 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.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.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Overlays; -using osuTK; namespace osu.Game.Screens.Edit.Setup { - public class SetupScreen : EditorScreen, ICanAcceptFiles + public class SetupScreen : EditorScreen { - public IEnumerable 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] - private OsuGameBase game { get; set; } + private OsuColour colours { get; set; } - [Resolved] - private MusicController music { get; set; } - - [Resolved] - private BeatmapManager beatmaps { get; set; } - - [Resolved(canBeNull: true)] - private Editor editor { get; set; } + [Cached] + protected readonly OverlayColourProvider ColourProvider; public SetupScreen() : base(EditorScreenMode.SongSetup) { + ColourProvider = new OverlayColourProvider(OverlayColourScheme.Green); } - [Resolved] - private OsuColour colours { get; set; } - [BackgroundDependencyLoader] private void load() { - Container audioTrackFileChooserContainer = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }; - Child = new Container { RelativeSizeAxes = Axes.Both, @@ -87,273 +44,33 @@ namespace osu.Game.Screens.Edit.Setup Colour = colours.GreySeafoamDark, RelativeSizeAxes = Axes.Both, }, - new OsuScrollContainer + new SectionsContainer { + FixedHeader = new SetupScreenHeader(), RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(10), - Child = flow = new FillFlowContainer + Children = new SetupSection[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - 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 - }, - } - }, + new ResourcesSection(), + new MetadataSection(), + } }, } } }; - - updateBackgroundSprite(); - - audioTrackTextBox.Current.BindValueChanged(audioTrackChanged); - - foreach (var item in flow.OfType()) - 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 => - { - 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); - }); - } - - 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 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 currentFile = new Bindable(); - - public FileChooserLabelledTextBox() + private class SetupScreenTitle : OverlayTitle { - currentFile.BindValueChanged(onFileSelected); - } - - private void onFileSelected(ValueChangedEvent file) - { - if (file.NewValue == null) - return; - - Target.Clear(); - Current.Value = file.NewValue.FullName; - } - - protected override OsuTextBox CreateTextBox() => - new FileChooserOsuTextBox + public SetupScreenTitle() { - 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); + Title = "beatmap setup"; + Description = "change general settings of your beatmap"; + IconTexture = "Icons/Hexacons/social"; } } } diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs new file mode 100644 index 0000000000..54e383a4d8 --- /dev/null +++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs @@ -0,0 +1,43 @@ +// 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; +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 + { + protected FillFlowContainer Flow; + + [Resolved] + protected OsuColour Colours { get; private set; } + + [Resolved] + protected IBindable Beatmap { get; private set; } + + public override void Add(Drawable drawable) => throw new InvalidOperationException("Use Flow.Add instead"); + + 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, + }; + } + } +} From 505dd37a75e98261394327771ffa764099716a73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:18:41 +0900 Subject: [PATCH 22/62] Make SettingsItem conform to IHasCurrentValue --- .../ManiaSettingsSubsection.cs | 4 ++-- .../UI/OsuSettingsSubsection.cs | 6 ++--- osu.Game.Tournament/Components/DateTextBox.cs | 18 +++++++------- .../Screens/Editors/RoundEditorScreen.cs | 12 +++++----- .../Screens/Editors/SeedingEditorScreen.cs | 10 ++++---- .../Screens/Editors/TeamEditorScreen.cs | 12 +++++----- .../Screens/Gameplay/GameplayScreen.cs | 4 ++-- .../Ladder/Components/LadderEditorSettings.cs | 12 +++++----- .../Screens/TeamIntro/SeedingScreen.cs | 2 +- .../Configuration/SettingSourceAttribute.cs | 12 +++++----- .../Sections/Audio/AudioDevicesSettings.cs | 2 +- .../Sections/Audio/MainMenuSettings.cs | 8 +++---- .../Settings/Sections/Audio/OffsetSettings.cs | 2 +- .../Settings/Sections/Audio/VolumeSettings.cs | 8 +++---- .../Sections/Debug/GeneralSettings.cs | 4 ++-- .../Sections/Gameplay/GeneralSettings.cs | 24 +++++++++---------- .../Sections/Gameplay/ModsSettings.cs | 2 +- .../Sections/Gameplay/SongSelectSettings.cs | 10 ++++---- .../Sections/General/LanguageSettings.cs | 2 +- .../Sections/General/LoginSettings.cs | 4 ++-- .../Sections/General/UpdateSettings.cs | 2 +- .../Sections/Graphics/DetailSettings.cs | 8 +++---- .../Sections/Graphics/LayoutSettings.cs | 20 ++++++++-------- .../Sections/Graphics/RendererSettings.cs | 6 ++--- .../Graphics/UserInterfaceSettings.cs | 6 ++--- .../Settings/Sections/Input/MouseSettings.cs | 12 +++++----- .../Settings/Sections/Online/WebSettings.cs | 4 ++-- .../Overlays/Settings/Sections/SkinSection.cs | 12 +++++----- osu.Game/Overlays/Settings/SettingsItem.cs | 4 ++-- .../Edit/Timing/SliderWithTextBoxInput.cs | 8 +++---- osu.Game/Screens/Edit/Timing/TimingSection.cs | 14 +++++------ .../Play/PlayerSettings/PlaybackSettings.cs | 4 ++-- .../Play/PlayerSettings/VisualSettings.cs | 4 ++-- 33 files changed, 131 insertions(+), 131 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index b470405df2..de77af8306 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Mania new SettingsEnumDropdown { LabelText = "Scrolling direction", - Bindable = config.GetBindable(ManiaRulesetSetting.ScrollDirection) + Current = config.GetBindable(ManiaRulesetSetting.ScrollDirection) }, new SettingsSlider { LabelText = "Scroll speed", - Bindable = config.GetBindable(ManiaRulesetSetting.ScrollTime), + Current = config.GetBindable(ManiaRulesetSetting.ScrollTime), KeyboardStep = 5 }, }; diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 88adf72551..3870f303b4 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -27,17 +27,17 @@ namespace osu.Game.Rulesets.Osu.UI new SettingsCheckbox { LabelText = "Snaking in sliders", - Bindable = config.GetBindable(OsuRulesetSetting.SnakingInSliders) + Current = config.GetBindable(OsuRulesetSetting.SnakingInSliders) }, new SettingsCheckbox { LabelText = "Snaking out sliders", - Bindable = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) + Current = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) }, new SettingsCheckbox { LabelText = "Cursor trail", - Bindable = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) + Current = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, }; } diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs index a1b5ac38ea..5782301a65 100644 --- a/osu.Game.Tournament/Components/DateTextBox.cs +++ b/osu.Game.Tournament/Components/DateTextBox.cs @@ -10,34 +10,34 @@ namespace osu.Game.Tournament.Components { public class DateTextBox : SettingsTextBox { - public new Bindable Bindable + public new Bindable Current { - get => bindable; + get => current; set { - bindable = value.GetBoundCopy(); - bindable.BindValueChanged(dto => - base.Bindable.Value = dto.NewValue.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"), true); + current = value.GetBoundCopy(); + current.BindValueChanged(dto => + 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. - private Bindable bindable = new Bindable(); + private Bindable current = new Bindable(); public DateTextBox() { - base.Bindable = new Bindable(); + base.Current = new Bindable(); ((OsuTextBox)Control).OnCommit += (sender, newText) => { try { - bindable.Value = DateTimeOffset.Parse(sender.Text); + current.Value = DateTimeOffset.Parse(sender.Text); } catch { // reset textbox content to its last valid state on a parse failure. - bindable.TriggerChange(); + current.TriggerChange(); } }; } diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 8b8078e119..069ddfa4db 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -63,25 +63,25 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Name", Width = 0.33f, - Bindable = Model.Name + Current = Model.Name }, new SettingsTextBox { LabelText = "Description", Width = 0.33f, - Bindable = Model.Description + Current = Model.Description }, new DateTextBox { LabelText = "Start Time", Width = 0.33f, - Bindable = Model.StartDate + Current = Model.StartDate }, new SettingsSlider { LabelText = "Best of", Width = 0.33f, - Bindable = Model.BestOf + Current = Model.BestOf }, new SettingsButton { @@ -186,14 +186,14 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "Beatmap ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmapId, + Current = beatmapId, }, new SettingsTextBox { LabelText = "Mods", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = mods, + Current = mods, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs index 0973a7dc75..7bd8d3f6a0 100644 --- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs @@ -74,13 +74,13 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Mod", Width = 0.33f, - Bindable = Model.Mod + Current = Model.Mod }, new SettingsSlider { LabelText = "Seed", Width = 0.33f, - Bindable = Model.Seed + Current = Model.Seed }, new SettingsButton { @@ -187,21 +187,21 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "Beatmap ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmapId, + Current = beatmapId, }, new SettingsSlider { LabelText = "Seed", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = beatmap.Seed + Current = beatmap.Seed }, new SettingsTextBox { LabelText = "Score", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = score, + Current = score, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index dbfcfe4225..7196f47bd6 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -102,31 +102,31 @@ namespace osu.Game.Tournament.Screens.Editors { LabelText = "Name", Width = 0.2f, - Bindable = Model.FullName + Current = Model.FullName }, new SettingsTextBox { LabelText = "Acronym", Width = 0.2f, - Bindable = Model.Acronym + Current = Model.Acronym }, new SettingsTextBox { LabelText = "Flag", Width = 0.2f, - Bindable = Model.FlagName + Current = Model.FlagName }, new SettingsTextBox { LabelText = "Seed", Width = 0.2f, - Bindable = Model.Seed + Current = Model.Seed }, new SettingsSlider { LabelText = "Last Year Placement", Width = 0.33f, - Bindable = Model.LastYearPlacing + Current = Model.LastYearPlacing }, new SettingsButton { @@ -247,7 +247,7 @@ namespace osu.Game.Tournament.Screens.Editors LabelText = "User ID", RelativeSizeAxes = Axes.None, Width = 200, - Bindable = userId, + Current = userId, }, drawableContainer = new Container { diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index e4e3842369..e4ec45c00e 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -113,13 +113,13 @@ namespace osu.Game.Tournament.Screens.Gameplay new SettingsSlider { LabelText = "Chroma width", - Bindable = LadderInfo.ChromaKeyWidth, + Current = LadderInfo.ChromaKeyWidth, KeyboardStep = 1, }, new SettingsSlider { LabelText = "Players per team", - Bindable = LadderInfo.PlayersPerTeam, + Current = LadderInfo.PlayersPerTeam, KeyboardStep = 1, } } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index b60eb814e5..cf4466a2e3 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -51,15 +51,15 @@ namespace osu.Game.Tournament.Screens.Ladder.Components editorInfo.Selected.ValueChanged += selection => { - roundDropdown.Bindable = selection.NewValue?.Round; + roundDropdown.Current = selection.NewValue?.Round; losersCheckbox.Current = selection.NewValue?.Losers; - dateTimeBox.Bindable = selection.NewValue?.Date; + dateTimeBox.Current = selection.NewValue?.Date; - team1Dropdown.Bindable = selection.NewValue?.Team1; - team2Dropdown.Bindable = selection.NewValue?.Team2; + team1Dropdown.Current = selection.NewValue?.Team1; + team2Dropdown.Current = selection.NewValue?.Team2; }; - roundDropdown.Bindable.ValueChanged += round => + roundDropdown.Current.ValueChanged += round => { if (editorInfo.Selected.Value?.Date.Value < round.NewValue?.StartDate.Value) { @@ -88,7 +88,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { public SettingsRoundDropdown(BindableList rounds) { - Bindable = new Bindable(); + Current = new Bindable(); foreach (var r in rounds.Prepend(new TournamentRound())) add(r); diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index eed3cac9f0..b343608e69 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro new SettingsTeamDropdown(LadderInfo.Teams) { LabelText = "Show specific team", - Bindable = currentTeam, + Current = currentTeam, } } } diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index fe487cb1d0..50069be4b2 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -57,7 +57,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber, + Current = bNumber, KeyboardStep = 0.1f, }; @@ -67,7 +67,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber, + Current = bNumber, KeyboardStep = 0.1f, }; @@ -77,7 +77,7 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber + Current = bNumber }; break; @@ -86,7 +86,7 @@ namespace osu.Game.Configuration yield return new SettingsCheckbox { LabelText = attr.Label, - Bindable = bBool + Current = bBool }; break; @@ -95,7 +95,7 @@ namespace osu.Game.Configuration yield return new SettingsTextBox { LabelText = attr.Label, - Bindable = bString + Current = bString }; break; @@ -105,7 +105,7 @@ namespace osu.Game.Configuration var dropdown = (Drawable)Activator.CreateInstance(dropdownType); dropdownType.GetProperty(nameof(SettingsDropdown.LabelText))?.SetValue(dropdown, attr.Label); - dropdownType.GetProperty(nameof(SettingsDropdown.Bindable))?.SetValue(dropdown, bindable); + dropdownType.GetProperty(nameof(SettingsDropdown.Current))?.SetValue(dropdown, bindable); yield return dropdown; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 3da64e0de4..bed74542c9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio updateItems(); - dropdown.Bindable = audio.AudioDevice; + dropdown.Current = audio.AudioDevice; audio.OnNewDevice += onDeviceChanged; audio.OnLostDevice += onDeviceChanged; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs index a303f93b34..d5de32ed05 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs @@ -21,23 +21,23 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsCheckbox { LabelText = "Interface voices", - Bindable = config.GetBindable(OsuSetting.MenuVoice) + Current = config.GetBindable(OsuSetting.MenuVoice) }, new SettingsCheckbox { LabelText = "osu! music theme", - Bindable = config.GetBindable(OsuSetting.MenuMusic) + Current = config.GetBindable(OsuSetting.MenuMusic) }, new SettingsDropdown { LabelText = "Intro sequence", - Bindable = config.GetBindable(OsuSetting.IntroSequence), + Current = config.GetBindable(OsuSetting.IntroSequence), Items = Enum.GetValues(typeof(IntroSequence)).Cast() }, new SettingsDropdown { LabelText = "Background source", - Bindable = config.GetBindable(OsuSetting.MenuBackgroundSource), + Current = config.GetBindable(OsuSetting.MenuBackgroundSource), Items = Enum.GetValues(typeof(BackgroundSource)).Cast() } }; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs index aaa4302553..c9a81b955b 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsSlider { LabelText = "Audio offset", - Bindable = config.GetBindable(OsuSetting.AudioOffset), + Current = config.GetBindable(OsuSetting.AudioOffset), KeyboardStep = 1f }, new SettingsButton diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index bda677ecd6..c172a76ab9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -20,28 +20,28 @@ namespace osu.Game.Overlays.Settings.Sections.Audio new SettingsSlider { LabelText = "Master", - Bindable = audio.Volume, + Current = audio.Volume, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Master (window inactive)", - Bindable = config.GetBindable(OsuSetting.VolumeInactive), + Current = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Effect", - Bindable = audio.VolumeSample, + Current = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Music", - Bindable = audio.VolumeTrack, + Current = audio.VolumeTrack, KeyboardStep = 0.01f, DisplayAsPercentage = true }, diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs index 9edb18e065..f05b876d8f 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs @@ -19,12 +19,12 @@ namespace osu.Game.Overlays.Settings.Sections.Debug new SettingsCheckbox { LabelText = "Show log overlay", - Bindable = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) + Current = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) }, new SettingsCheckbox { LabelText = "Bypass front-to-back render pass", - Bindable = config.GetBindable(DebugSetting.BypassFrontToBackPass) + Current = config.GetBindable(DebugSetting.BypassFrontToBackPass) } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 0149e6c3a6..73968761e2 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -21,62 +21,62 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsSlider { LabelText = "Background dim", - Bindable = config.GetBindable(OsuSetting.DimLevel), + Current = config.GetBindable(OsuSetting.DimLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Background blur", - Bindable = config.GetBindable(OsuSetting.BlurLevel), + Current = config.GetBindable(OsuSetting.BlurLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsCheckbox { LabelText = "Lighten playfield during breaks", - Bindable = config.GetBindable(OsuSetting.LightenDuringBreaks) + Current = config.GetBindable(OsuSetting.LightenDuringBreaks) }, new SettingsCheckbox { LabelText = "Show score overlay", - Bindable = config.GetBindable(OsuSetting.ShowInterface) + Current = config.GetBindable(OsuSetting.ShowInterface) }, new SettingsCheckbox { LabelText = "Show difficulty graph on progress bar", - Bindable = config.GetBindable(OsuSetting.ShowProgressGraph) + Current = config.GetBindable(OsuSetting.ShowProgressGraph) }, new SettingsCheckbox { LabelText = "Show health display even when you can't fail", - Bindable = config.GetBindable(OsuSetting.ShowHealthDisplayWhenCantFail), + Current = config.GetBindable(OsuSetting.ShowHealthDisplayWhenCantFail), Keywords = new[] { "hp", "bar" } }, new SettingsCheckbox { LabelText = "Fade playfield to red when health is low", - Bindable = config.GetBindable(OsuSetting.FadePlayfieldWhenHealthLow), + Current = config.GetBindable(OsuSetting.FadePlayfieldWhenHealthLow), }, new SettingsCheckbox { LabelText = "Always show key overlay", - Bindable = config.GetBindable(OsuSetting.KeyOverlay) + Current = config.GetBindable(OsuSetting.KeyOverlay) }, new SettingsCheckbox { LabelText = "Positional hitsounds", - Bindable = config.GetBindable(OsuSetting.PositionalHitSounds) + Current = config.GetBindable(OsuSetting.PositionalHitSounds) }, new SettingsEnumDropdown { LabelText = "Score meter type", - Bindable = config.GetBindable(OsuSetting.ScoreMeter) + Current = config.GetBindable(OsuSetting.ScoreMeter) }, new SettingsEnumDropdown { LabelText = "Score display mode", - Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + Current = config.GetBindable(OsuSetting.ScoreDisplayMode) } }; @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay Add(new SettingsCheckbox { LabelText = "Disable Windows key during gameplay", - Bindable = config.GetBindable(OsuSetting.GameplayDisableWinKey) + Current = config.GetBindable(OsuSetting.GameplayDisableWinKey) }); } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs index 0babb98066..2b2fb9cef7 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsCheckbox { LabelText = "Increase visibility of first object when visual impairment mods are enabled", - Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), + Current = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index 0c42247993..b26876556e 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -31,31 +31,31 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay new SettingsCheckbox { LabelText = "Right mouse drag to absolute scroll", - Bindable = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), + Current = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), }, new SettingsCheckbox { LabelText = "Show converted beatmaps", - Bindable = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), + Current = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), }, new SettingsSlider { LabelText = "Display beatmaps from", - Bindable = config.GetBindable(OsuSetting.DisplayStarsMinimum), + Current = config.GetBindable(OsuSetting.DisplayStarsMinimum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsSlider { LabelText = "up to", - Bindable = config.GetBindable(OsuSetting.DisplayStarsMaximum), + Current = config.GetBindable(OsuSetting.DisplayStarsMaximum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsEnumDropdown { LabelText = "Random selection algorithm", - Bindable = config.GetBindable(OsuSetting.RandomSelectAlgorithm), + Current = config.GetBindable(OsuSetting.RandomSelectAlgorithm), } }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index 236bfbecc3..44e42ecbfe 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.General new SettingsCheckbox { LabelText = "Prefer metadata in original language", - Bindable = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) + Current = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index f96e204f62..9e358d0cf5 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -240,12 +240,12 @@ namespace osu.Game.Overlays.Settings.Sections.General new SettingsCheckbox { LabelText = "Remember username", - Bindable = config.GetBindable(OsuSetting.SaveUsername), + Current = config.GetBindable(OsuSetting.SaveUsername), }, new SettingsCheckbox { LabelText = "Stay signed in", - Bindable = config.GetBindable(OsuSetting.SavePassword), + Current = config.GetBindable(OsuSetting.SavePassword), }, new Container { diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 9c7d0b0be4..a59a6b00b9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Add(new SettingsEnumDropdown { LabelText = "Release stream", - Bindable = config.GetBindable(OsuSetting.ReleaseStream), + Current = config.GetBindable(OsuSetting.ReleaseStream), }); if (updateManager?.CanCheckForUpdate == true) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index 3089040f96..30caa45995 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -19,22 +19,22 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsCheckbox { LabelText = "Storyboard / Video", - Bindable = config.GetBindable(OsuSetting.ShowStoryboard) + Current = config.GetBindable(OsuSetting.ShowStoryboard) }, new SettingsCheckbox { LabelText = "Hit Lighting", - Bindable = config.GetBindable(OsuSetting.HitLighting) + Current = config.GetBindable(OsuSetting.HitLighting) }, new SettingsEnumDropdown { LabelText = "Screenshot format", - Bindable = config.GetBindable(OsuSetting.ScreenshotFormat) + Current = config.GetBindable(OsuSetting.ScreenshotFormat) }, new SettingsCheckbox { LabelText = "Show menu cursor in screenshots", - Bindable = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) + Current = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 4312b319c0..14b8dbfac0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics windowModeDropdown = new SettingsDropdown { LabelText = "Screen mode", - Bindable = config.GetBindable(FrameworkSetting.WindowMode), + Current = config.GetBindable(FrameworkSetting.WindowMode), ItemSource = windowModes, }, resolutionSettingsContainer = new Container @@ -74,14 +74,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = "UI Scaling", TransferValueOnCommit = true, - Bindable = osuConfig.GetBindable(OsuSetting.UIScale), + Current = osuConfig.GetBindable(OsuSetting.UIScale), KeyboardStep = 0.01f, Keywords = new[] { "scale", "letterbox" }, }, new SettingsEnumDropdown { LabelText = "Screen Scaling", - Bindable = osuConfig.GetBindable(OsuSetting.Scaling), + Current = osuConfig.GetBindable(OsuSetting.Scaling), Keywords = new[] { "scale", "letterbox" }, }, scalingSettings = new FillFlowContainer> @@ -97,28 +97,28 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsSlider { LabelText = "Horizontal position", - Bindable = scalingPositionX, + Current = scalingPositionX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical position", - Bindable = scalingPositionY, + Current = scalingPositionY, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Horizontal scale", - Bindable = scalingSizeX, + Current = scalingSizeX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical scale", - Bindable = scalingSizeY, + Current = scalingSizeY, KeyboardStep = 0.01f, 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(); @@ -137,10 +137,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics LabelText = "Resolution", ShowsDefaultIndicator = false, Items = resolutions, - Bindable = sizeFullscreen + Current = sizeFullscreen }; - windowModeDropdown.Bindable.BindValueChanged(mode => + windowModeDropdown.Current.BindValueChanged(mode => { if (mode.NewValue == WindowMode.Fullscreen) { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 69ff9b43e5..8773e6763c 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -23,17 +23,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsEnumDropdown { LabelText = "Frame limiter", - Bindable = config.GetBindable(FrameworkSetting.FrameSync) + Current = config.GetBindable(FrameworkSetting.FrameSync) }, new SettingsEnumDropdown { LabelText = "Threading mode", - Bindable = config.GetBindable(FrameworkSetting.ExecutionMode) + Current = config.GetBindable(FrameworkSetting.ExecutionMode) }, new SettingsCheckbox { LabelText = "Show FPS", - Bindable = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) + Current = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs index a8953ac3a2..38c30ddd64 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/UserInterfaceSettings.cs @@ -20,17 +20,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsCheckbox { LabelText = "Rotate cursor when dragging", - Bindable = config.GetBindable(OsuSetting.CursorRotation) + Current = config.GetBindable(OsuSetting.CursorRotation) }, new SettingsCheckbox { LabelText = "Parallax", - Bindable = config.GetBindable(OsuSetting.MenuParallax) + Current = config.GetBindable(OsuSetting.MenuParallax) }, new SettingsSlider { LabelText = "Hold-to-confirm activation time", - Bindable = config.GetBindable(OsuSetting.UIHoldActivationDelay), + Current = config.GetBindable(OsuSetting.UIHoldActivationDelay), KeyboardStep = 50 }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index d27ab63fb7..5227e328ec 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -35,32 +35,32 @@ namespace osu.Game.Overlays.Settings.Sections.Input new SettingsCheckbox { LabelText = "Raw input", - Bindable = rawInputToggle + Current = rawInputToggle }, new SensitivitySetting { LabelText = "Cursor sensitivity", - Bindable = sensitivityBindable + Current = sensitivityBindable }, new SettingsCheckbox { LabelText = "Map absolute input to window", - Bindable = config.GetBindable(FrameworkSetting.MapAbsoluteInputToWindow) + Current = config.GetBindable(FrameworkSetting.MapAbsoluteInputToWindow) }, new SettingsEnumDropdown { LabelText = "Confine mouse cursor to window", - Bindable = config.GetBindable(FrameworkSetting.ConfineMouseMode), + Current = config.GetBindable(FrameworkSetting.ConfineMouseMode), }, new SettingsCheckbox { LabelText = "Disable mouse wheel during gameplay", - Bindable = osuConfig.GetBindable(OsuSetting.MouseDisableWheel) + Current = osuConfig.GetBindable(OsuSetting.MouseDisableWheel) }, new SettingsCheckbox { LabelText = "Disable mouse buttons during gameplay", - Bindable = osuConfig.GetBindable(OsuSetting.MouseDisableButtons) + Current = osuConfig.GetBindable(OsuSetting.MouseDisableButtons) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 23513eade8..6461bd7b93 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -19,13 +19,13 @@ namespace osu.Game.Overlays.Settings.Sections.Online new SettingsCheckbox { LabelText = "Warn about opening external links", - Bindable = config.GetBindable(OsuSetting.ExternalLinkWarning) + Current = config.GetBindable(OsuSetting.ExternalLinkWarning) }, new SettingsCheckbox { LabelText = "Prefer downloads without video", Keywords = new[] { "no-video" }, - Bindable = config.GetBindable(OsuSetting.PreferNoVideo) + Current = config.GetBindable(OsuSetting.PreferNoVideo) }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 596d3a9801..1ade4befdc 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -47,29 +47,29 @@ namespace osu.Game.Overlays.Settings.Sections new SettingsSlider { LabelText = "Menu cursor size", - Bindable = config.GetBindable(OsuSetting.MenuCursorSize), + Current = config.GetBindable(OsuSetting.MenuCursorSize), KeyboardStep = 0.01f }, new SettingsSlider { LabelText = "Gameplay cursor size", - Bindable = config.GetBindable(OsuSetting.GameplayCursorSize), + Current = config.GetBindable(OsuSetting.GameplayCursorSize), KeyboardStep = 0.01f }, new SettingsCheckbox { LabelText = "Adjust gameplay cursor size based on current beatmap", - Bindable = config.GetBindable(OsuSetting.AutoCursorSize) + Current = config.GetBindable(OsuSetting.AutoCursorSize) }, new SettingsCheckbox { LabelText = "Beatmap skins", - Bindable = config.GetBindable(OsuSetting.BeatmapSkins) + Current = config.GetBindable(OsuSetting.BeatmapSkins) }, new SettingsCheckbox { LabelText = "Beatmap hitsounds", - Bindable = config.GetBindable(OsuSetting.BeatmapHitsounds) + Current = config.GetBindable(OsuSetting.BeatmapHitsounds) }, }; @@ -81,7 +81,7 @@ namespace osu.Game.Overlays.Settings.Sections config.BindWith(OsuSetting.Skin, configBindable); - skinDropdown.Bindable = dropdownBindable; + skinDropdown.Current = dropdownBindable; skinDropdown.Items = skins.GetAllUsableSkins().ToArray(); // Todo: This should not be necessary when OsuConfigManager is databased diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index c2dd40d2a6..ad6aaafd9d 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract class SettingsItem : Container, IFilterable, ISettingsItem + public abstract class SettingsItem : Container, IFilterable, ISettingsItem, IHasCurrentValue { protected abstract Drawable CreateControl(); @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Settings } } - public virtual Bindable Bindable + public virtual Bindable Current { get => controlWithCurrent.Current; set => controlWithCurrent.Current = value; diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index d5afc8978d..f2f9f76143 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Edit.Timing { - internal class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue + public class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue where T : struct, IEquatable, IComparable, IConvertible { private readonly SettingsSlider slider; @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Timing try { - slider.Bindable.Parse(t.Text); + slider.Current.Parse(t.Text); } catch { @@ -71,8 +71,8 @@ namespace osu.Game.Screens.Edit.Timing public Bindable Current { - get => slider.Bindable; - set => slider.Bindable = value; + get => slider.Current; + set => slider.Current = value; } } } diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 2ab8703cc4..1ae2a86885 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -36,14 +36,14 @@ namespace osu.Game.Screens.Edit.Timing { if (point.NewValue != null) { - bpmSlider.Bindable = point.NewValue.BeatLengthBindable; - bpmSlider.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); + bpmSlider.Current = point.NewValue.BeatLengthBindable; + bpmSlider.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); bpmTextEntry.Bindable = point.NewValue.BeatLengthBindable; // no need to hook change handler here as it's the same bindable as above - timeSignature.Bindable = point.NewValue.TimeSignatureBindable; - timeSignature.Bindable.BindValueChanged(_ => ChangeHandler?.SaveState()); + timeSignature.Current = point.NewValue.TimeSignatureBindable; + timeSignature.Current.BindValueChanged(_ => ChangeHandler?.SaveState()); } } @@ -121,14 +121,14 @@ namespace osu.Game.Screens.Edit.Timing beatLengthBindable.BindValueChanged(beatLength => updateCurrent(beatLengthToBpm(beatLength.NewValue)), true); bpmBindable.BindValueChanged(bpm => beatLengthBindable.Value = beatLengthToBpm(bpm.NewValue)); - base.Bindable = bpmBindable; + base.Current = bpmBindable; TransferValueOnCommit = true; } - public override Bindable Bindable + public override Bindable Current { - get => base.Bindable; + get => base.Current; set { // incoming will be beat length, not bpm diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 24ddc277cd..16e29ac3c8 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -51,14 +51,14 @@ namespace osu.Game.Screens.Play.PlayerSettings } }, }, - rateSlider = new PlayerSliderBar { Bindable = UserPlaybackRate } + rateSlider = new PlayerSliderBar { Current = UserPlaybackRate } }; } protected override void 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); } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e06cf5c6d5..8f29fe7893 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -50,8 +50,8 @@ namespace osu.Game.Screens.Play.PlayerSettings [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - dimSliderBar.Bindable = config.GetBindable(OsuSetting.DimLevel); - blurSliderBar.Bindable = config.GetBindable(OsuSetting.BlurLevel); + dimSliderBar.Current = config.GetBindable(OsuSetting.DimLevel); + blurSliderBar.Current = config.GetBindable(OsuSetting.BlurLevel); showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapHitsoundsToggle.Current = config.GetBindable(OsuSetting.BeatmapHitsounds); From e1a6f47d90b226ed0525d4e113cdac3b59e05afb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 16:40:47 +0900 Subject: [PATCH 23/62] Add the most basic implementation of LabelledSliderBar feasible --- .../TestSceneLabelledSliderBar.cs | 46 +++++++++++++++++++ .../UserInterfaceV2/LabelledSliderBar.cs | 24 ++++++++++ 2 files changed, 70 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs create mode 100644 osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs new file mode 100644 index 0000000000..393420e700 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . 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 component; + + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500, + AutoSizeAxes = Axes.Y, + Child = component = new LabelledSliderBar + { + 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; + }); + } + } +} diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs new file mode 100644 index 0000000000..cba94e314b --- /dev/null +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs @@ -0,0 +1,24 @@ +// 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.Graphics; +using osu.Game.Overlays.Settings; + +namespace osu.Game.Graphics.UserInterfaceV2 +{ + public class LabelledSliderBar : LabelledComponent, TNumber> + where TNumber : struct, IEquatable, IComparable, IConvertible + { + public LabelledSliderBar() + : base(true) + { + } + + protected override SettingsSlider CreateComponent() => new SettingsSlider + { + TransferValueOnCommit = true, + RelativeSizeAxes = Axes.X, + }; + } +} From 13b67b93a5ba3ff79a78b3a92a7ae1c60f6d0f7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 15:51:40 +0900 Subject: [PATCH 24/62] Add difficulty section --- .../Screens/Edit/Setup/DifficultySection.cs | 25 +++++++++++++++++++ osu.Game/Screens/Edit/Setup/SetupScreen.cs | 1 + 2 files changed, 26 insertions(+) create mode 100644 osu.Game/Screens/Edit/Setup/DifficultySection.cs diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs new file mode 100644 index 0000000000..952ce90273 --- /dev/null +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Edit.Setup +{ + internal class DifficultySection : SetupSection + { + [BackgroundDependencyLoader] + private void load() + { + Flow.Children = new Drawable[] + { + new OsuSpriteText + { + Text = "Difficulty settings" + }, + new LabelledSlider() + }; + } + } +} diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index cd4f6733c0..1c3cbb7206 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -52,6 +52,7 @@ namespace osu.Game.Screens.Edit.Setup { new ResourcesSection(), new MetadataSection(), + new DifficultySection(), } }, } From 6d7f12ad4bc68c1573a71b8811e8b0a4adebc09e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:01:50 +0900 Subject: [PATCH 25/62] Add basic difficulty setting sliders --- .../Screens/Edit/Setup/DifficultySection.cs | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 952ce90273..0434c1cf1f 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -1,14 +1,23 @@ // Copyright (c) ppy Pty Ltd . 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.Bindables; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.Edit.Setup { internal class DifficultySection : SetupSection { + private LabelledSliderBar circleSizeSlider; + private LabelledSliderBar healthDrainSlider; + private LabelledSliderBar approachRateSlider; + private LabelledSliderBar overallDifficultySlider; + [BackgroundDependencyLoader] private void load() { @@ -18,8 +27,60 @@ namespace osu.Game.Screens.Edit.Setup { Text = "Difficulty settings" }, - new LabelledSlider() + circleSizeSlider = new LabelledSliderBar + { + Label = "Circle Size", + Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize) + { + Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, + MinValue = 2, + MaxValue = 7 + } + }, + healthDrainSlider = new LabelledSliderBar + { + Label = "Health Drain", + Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.DrainRate) + { + Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, + MinValue = 0, + MaxValue = 10 + } + }, + approachRateSlider = new LabelledSliderBar + { + Label = "Approach Rate", + Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.ApproachRate) + { + Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, + MinValue = 0, + MaxValue = 10 + } + }, + overallDifficultySlider = new LabelledSliderBar + { + Label = "Overall Difficulty", + Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty) + { + Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, + MinValue = 0, + MaxValue = 10 + } + }, }; + + foreach (var item in Flow.OfType>()) + item.Current.ValueChanged += onValueChanged; + } + + private void onValueChanged(ValueChangedEvent args) + { + // 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.BeatmapInfo.BaseDifficulty.CircleSize = circleSizeSlider.Current.Value; + Beatmap.Value.BeatmapInfo.BaseDifficulty.DrainRate = healthDrainSlider.Current.Value; + Beatmap.Value.BeatmapInfo.BaseDifficulty.ApproachRate = approachRateSlider.Current.Value; + Beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty = overallDifficultySlider.Current.Value; } } } From 7a20a34aff82cbf491a21da19c18ae156d346378 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:12:19 +0900 Subject: [PATCH 26/62] Add support to EditorBeatmap to update all hitobjects --- osu.Game/Screens/Edit/EditorBeatmap.cs | 9 +++++++++ osu.Game/Screens/Edit/Setup/DifficultySection.cs | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 3248c5b8be..d37b7dd2b5 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -258,5 +258,14 @@ namespace osu.Game.Screens.Edit public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; public int BeatDivisor => beatDivisor?.Value ?? 1; + + /// + /// Update all hit objects with potentially changed difficulty or control point data. + /// + public void UpdateBeatmap() + { + foreach (var h in HitObjects) + pendingUpdates.Add(h); + } } } diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 0434c1cf1f..ce6f617f37 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -13,6 +13,9 @@ namespace osu.Game.Screens.Edit.Setup { internal class DifficultySection : SetupSection { + [Resolved] + private EditorBeatmap editorBeatmap { get; set; } + private LabelledSliderBar circleSizeSlider; private LabelledSliderBar healthDrainSlider; private LabelledSliderBar approachRateSlider; @@ -81,6 +84,8 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.Value.BeatmapInfo.BaseDifficulty.DrainRate = healthDrainSlider.Current.Value; Beatmap.Value.BeatmapInfo.BaseDifficulty.ApproachRate = approachRateSlider.Current.Value; Beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty = overallDifficultySlider.Current.Value; + + editorBeatmap.UpdateBeatmap(); } } } From 7e8ab1cb9587913ba6c50ec362c871e7b4240e73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:17:03 +0900 Subject: [PATCH 27/62] Add description text --- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index ce6f617f37..4ed8d0164b 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -32,7 +32,8 @@ namespace osu.Game.Screens.Edit.Setup }, circleSizeSlider = new LabelledSliderBar { - Label = "Circle Size", + Label = "Object Size", + Description = "The size of all hit objects", Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize) { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, @@ -43,6 +44,7 @@ namespace osu.Game.Screens.Edit.Setup healthDrainSlider = new LabelledSliderBar { Label = "Health Drain", + Description = "The rate of passive health drain throughout playable time", Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.DrainRate) { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, @@ -53,6 +55,7 @@ namespace osu.Game.Screens.Edit.Setup approachRateSlider = new LabelledSliderBar { Label = "Approach Rate", + Description = "The speed at which objects are presented to the player", Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.ApproachRate) { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, @@ -63,6 +66,7 @@ namespace osu.Game.Screens.Edit.Setup overallDifficultySlider = new LabelledSliderBar { Label = "Overall Difficulty", + Description = "The harshness of hit windows and difficulty of special objects (ie. spinners)", Current = new BindableFloat(Beatmap.Value.BeatmapInfo.BaseDifficulty.OverallDifficulty) { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, From 3ce234d552bb5ae708b8915c4bfad7b7b8e7c896 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:47:22 +0900 Subject: [PATCH 28/62] Seek at 4x normal speed when holding shift This matches osu-stable 1:1. Not sure if it feels better or not but let's stick with what people are used to for the time being. --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 875ab25003..4b4266d049 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -589,7 +589,7 @@ namespace osu.Game.Screens.Edit private void seek(UIEvent e, int direction) { - double amount = e.ShiftPressed ? 2 : 1; + double amount = e.ShiftPressed ? 4 : 1; if (direction < 1) clock.SeekBackward(!clock.IsRunning, amount); From b1a64f89d78603ef86157940ec582127698f1707 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 17:49:12 +0900 Subject: [PATCH 29/62] Increase backwards seek magnitude when the track is running This matches osu-stable. When the track is running, seeking backwards (against the flow) is harder than seeking forwards. Adding a mutliplier makes it feel much better. Note that this is additive not multiplicative because for larger seeks the (where `amount` > 1) we don't want to jump an insanely huge amount - just offset the seek slightly to account for playing audio. --- osu.Game/Screens/Edit/EditorClock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 4b7cd82637..64ed34f5ec 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit /// /// Whether to snap to the closest beat after seeking. /// The relative amount (magnitude) which should be seeked. - 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)); /// /// Seeks forwards by one beat length. From 1877312a917ce017b5fa8e58951a4c373cb7cecb Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Tue, 6 Oct 2020 19:52:18 +1030 Subject: [PATCH 30/62] Rename DuringGameplay --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Input/ConfineMouseTracker.cs | 4 ++-- osu.Game/Input/OsuConfineMouseMode.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 78179a781a..71cbdb345c 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -70,7 +70,7 @@ namespace osu.Game.Configuration Set(OsuSetting.MouseDisableButtons, false); Set(OsuSetting.MouseDisableWheel, false); - Set(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.DuringGameplay); + Set(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.WhenOverlaysDisabled); // Graphics Set(OsuSetting.ShowFpsDisplay, false); diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 6565967d1d..653622e881 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -16,7 +16,7 @@ namespace osu.Game.Input /// Connects with , /// while optionally binding an mode, usually that of the current . /// It is assumed that while overlay activation is , we should also confine the - /// mouse cursor if it has been requested with . + /// mouse cursor if it has been requested with . /// public class ConfineMouseTracker : Component { @@ -52,7 +52,7 @@ namespace osu.Game.Input frameworkConfineMode.Value = ConfineMouseMode.Fullscreen; break; - case OsuConfineMouseMode.DuringGameplay: + case OsuConfineMouseMode.WhenOverlaysDisabled: frameworkConfineMode.Value = OverlayActivationMode.Value == OverlayActivation.Disabled ? ConfineMouseMode.Always : ConfineMouseMode.Never; break; diff --git a/osu.Game/Input/OsuConfineMouseMode.cs b/osu.Game/Input/OsuConfineMouseMode.cs index 32b456395c..53e352c8bd 100644 --- a/osu.Game/Input/OsuConfineMouseMode.cs +++ b/osu.Game/Input/OsuConfineMouseMode.cs @@ -27,7 +27,7 @@ namespace osu.Game.Input /// but may otherwise move freely. /// [Description("During Gameplay")] - DuringGameplay, + WhenOverlaysDisabled, /// /// The mouse cursor will always be locked to the window bounds while the game has focus. From 782fc1d60fe1c10768ef393ba3102a77e3237662 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Tue, 6 Oct 2020 20:11:48 +1030 Subject: [PATCH 31/62] Use OsuGame.OverlayActivationMode rather than per-Player --- osu.Game/Input/ConfineMouseTracker.cs | 19 ++++++------------- osu.Game/Input/OsuConfineMouseMode.cs | 2 +- osu.Game/Screens/Play/Player.cs | 6 ------ 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 653622e881..3b54c03bb0 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -8,13 +8,12 @@ using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Configuration; using osu.Game.Overlays; -using osu.Game.Screens.Play; namespace osu.Game.Input { /// /// Connects with , - /// while optionally binding an mode, usually that of the current . + /// while binding . /// It is assumed that while overlay activation is , we should also confine the /// mouse cursor if it has been requested with . /// @@ -22,22 +21,16 @@ namespace osu.Game.Input { private Bindable frameworkConfineMode; private Bindable osuConfineMode; - - /// - /// The bindable used to indicate whether gameplay is active. - /// Should be bound to the corresponding bindable of the current . - /// Defaults to to assume that all other screens are considered "not gameplay". - /// - public IBindable OverlayActivationMode { get; } = new Bindable(OverlayActivation.All); + private IBindable overlayActivationMode; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) + private void load(OsuGame game, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) { frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); osuConfineMode.ValueChanged += _ => updateConfineMode(); - - OverlayActivationMode.BindValueChanged(_ => updateConfineMode(), true); + overlayActivationMode = game.OverlayActivationMode.GetBoundCopy(); + overlayActivationMode.BindValueChanged(_ => updateConfineMode(), true); } private void updateConfineMode() @@ -53,7 +46,7 @@ namespace osu.Game.Input break; case OsuConfineMouseMode.WhenOverlaysDisabled: - frameworkConfineMode.Value = OverlayActivationMode.Value == OverlayActivation.Disabled ? ConfineMouseMode.Always : ConfineMouseMode.Never; + frameworkConfineMode.Value = overlayActivationMode?.Value == OverlayActivation.Disabled ? ConfineMouseMode.Always : ConfineMouseMode.Never; break; case OsuConfineMouseMode.Always: diff --git a/osu.Game/Input/OsuConfineMouseMode.cs b/osu.Game/Input/OsuConfineMouseMode.cs index 53e352c8bd..e8411a3d9f 100644 --- a/osu.Game/Input/OsuConfineMouseMode.cs +++ b/osu.Game/Input/OsuConfineMouseMode.cs @@ -23,7 +23,7 @@ namespace osu.Game.Input Fullscreen, /// - /// The mouse cursor will be locked to the window bounds during gameplay, + /// The mouse cursor will be locked to the window bounds while overlays are disabled, /// but may otherwise move freely. /// [Description("During Gameplay")] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index de67b2d46d..175722c44e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -18,7 +18,6 @@ using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics.Containers; -using osu.Game.Input; using osu.Game.IO.Archives; using osu.Game.Online.API; using osu.Game.Overlays; @@ -67,9 +66,6 @@ namespace osu.Game.Screens.Play private Bindable mouseWheelDisabled; - [Resolved(CanBeNull = true)] - private ConfineMouseTracker confineMouseTracker { get; set; } - private readonly Bindable storyboardReplacesBackground = new Bindable(); public int RestartCount; @@ -229,8 +225,6 @@ namespace osu.Game.Screens.Play DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); - confineMouseTracker?.OverlayActivationMode.BindTo(OverlayActivationMode); - // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); From e64cee10b8fa82ca05e2d365c760924a75fd3cfe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:07:31 +0900 Subject: [PATCH 32/62] Add obsoleted Bindable property back to SettingsItem for compatibility --- osu.Game/Overlays/Settings/SettingsItem.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index ad6aaafd9d..278479e04f 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -54,6 +54,13 @@ namespace osu.Game.Overlays.Settings } } + [Obsolete("Use Current instead")] // Can be removed 20210406 + public Bindable Bindable + { + get => Current; + set => Current = value; + } + public virtual Bindable Current { get => controlWithCurrent.Current; From a2796d2c017bce185aaca88e3b581d56599888b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:20:53 +0900 Subject: [PATCH 33/62] Add repeats display to timeline blueprints --- .../Timeline/TimelineHitObjectBlueprint.cs | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index bc2ccfc605..f0757a3dda 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -199,7 +199,40 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline base.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; From 06a51297a3f2b20d40a99e31d9ee024dea020261 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:26:57 +0900 Subject: [PATCH 34/62] Use content instead of exposing the flow container --- osu.Game/Screens/Edit/Setup/MetadataSection.cs | 4 ++-- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 2 +- osu.Game/Screens/Edit/Setup/SetupSection.cs | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs index 31a2c2ce1a..4ddee2acc6 100644 --- a/osu.Game/Screens/Edit/Setup/MetadataSection.cs +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Edit.Setup [BackgroundDependencyLoader] private void load() { - Flow.Children = new Drawable[] + Children = new Drawable[] { new OsuSpriteText { @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Edit.Setup }, }; - foreach (var item in Flow.OfType()) + foreach (var item in Children.OfType()) item.OnCommit += onCommit; } diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 86d7968856..17ecfdd52e 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit.Setup AutoSizeAxes = Axes.Y, }; - Flow.Children = new Drawable[] + Children = new Drawable[] { backgroundSpriteContainer = new Container { diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs index 54e383a4d8..cdf17d355e 100644 --- a/osu.Game/Screens/Edit/Setup/SetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs @@ -1,7 +1,6 @@ // 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; @@ -14,7 +13,7 @@ namespace osu.Game.Screens.Edit.Setup { internal class SetupSection : Container { - protected FillFlowContainer Flow; + private readonly FillFlowContainer flow; [Resolved] protected OsuColour Colours { get; private set; } @@ -22,7 +21,7 @@ namespace osu.Game.Screens.Edit.Setup [Resolved] protected IBindable Beatmap { get; private set; } - public override void Add(Drawable drawable) => throw new InvalidOperationException("Use Flow.Add instead"); + protected override Container Content => flow; public SetupSection() { @@ -31,7 +30,7 @@ namespace osu.Game.Screens.Edit.Setup Padding = new MarginPadding(10); - InternalChild = Flow = new FillFlowContainer + InternalChild = flow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, From 461be02e6f9ff563ebe458603f9ecaaf6fd9aa26 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:34:21 +0900 Subject: [PATCH 35/62] Update with underlying changes --- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 4ed8d0164b..f23bc0f3b2 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Edit.Setup [BackgroundDependencyLoader] private void load() { - Flow.Children = new Drawable[] + Children = new Drawable[] { new OsuSpriteText { @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Setup }, }; - foreach (var item in Flow.OfType>()) + foreach (var item in Children.OfType>()) item.Current.ValueChanged += onValueChanged; } From 478f2dec9624f13c9fdf8503774094a19da2e9da Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Tue, 6 Oct 2020 22:39:35 +1030 Subject: [PATCH 36/62] Maintain the current gameplay state in OsuGame --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Input/ConfineMouseTracker.cs | 19 +++++++-------- osu.Game/Input/OsuConfineMouseMode.cs | 4 ++-- osu.Game/OsuGame.cs | 5 ++++ osu.Game/Screens/Play/Player.cs | 28 ++++++++++++---------- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 71cbdb345c..78179a781a 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -70,7 +70,7 @@ namespace osu.Game.Configuration Set(OsuSetting.MouseDisableButtons, false); Set(OsuSetting.MouseDisableWheel, false); - Set(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.WhenOverlaysDisabled); + Set(OsuSetting.ConfineMouseMode, OsuConfineMouseMode.DuringGameplay); // Graphics Set(OsuSetting.ShowFpsDisplay, false); diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 3b54c03bb0..c1089874ae 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -7,30 +7,29 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Configuration; -using osu.Game.Overlays; namespace osu.Game.Input { /// - /// Connects with , - /// while binding . - /// It is assumed that while overlay activation is , we should also confine the - /// mouse cursor if it has been requested with . + /// Connects with . + /// If is true, we should also confine the mouse cursor if it has been + /// requested with . /// public class ConfineMouseTracker : Component { private Bindable frameworkConfineMode; private Bindable osuConfineMode; - private IBindable overlayActivationMode; + private IBindable isGameplay; [BackgroundDependencyLoader] private void load(OsuGame game, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) { frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); + isGameplay = game.IsGameplay.GetBoundCopy(); + osuConfineMode.ValueChanged += _ => updateConfineMode(); - overlayActivationMode = game.OverlayActivationMode.GetBoundCopy(); - overlayActivationMode.BindValueChanged(_ => updateConfineMode(), true); + isGameplay.BindValueChanged(_ => updateConfineMode(), true); } private void updateConfineMode() @@ -45,8 +44,8 @@ namespace osu.Game.Input frameworkConfineMode.Value = ConfineMouseMode.Fullscreen; break; - case OsuConfineMouseMode.WhenOverlaysDisabled: - frameworkConfineMode.Value = overlayActivationMode?.Value == OverlayActivation.Disabled ? ConfineMouseMode.Always : ConfineMouseMode.Never; + case OsuConfineMouseMode.DuringGameplay: + frameworkConfineMode.Value = isGameplay.Value ? ConfineMouseMode.Always : ConfineMouseMode.Never; break; case OsuConfineMouseMode.Always: diff --git a/osu.Game/Input/OsuConfineMouseMode.cs b/osu.Game/Input/OsuConfineMouseMode.cs index e8411a3d9f..32b456395c 100644 --- a/osu.Game/Input/OsuConfineMouseMode.cs +++ b/osu.Game/Input/OsuConfineMouseMode.cs @@ -23,11 +23,11 @@ namespace osu.Game.Input Fullscreen, /// - /// The mouse cursor will be locked to the window bounds while overlays are disabled, + /// The mouse cursor will be locked to the window bounds during gameplay, /// but may otherwise move freely. /// [Description("During Gameplay")] - WhenOverlaysDisabled, + DuringGameplay, /// /// The mouse cursor will always be locked to the window bounds while the game has focus. diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 06e6e4bfb0..466ff13615 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -97,6 +97,11 @@ namespace osu.Game /// public readonly IBindable OverlayActivationMode = new Bindable(); + /// + /// Whether gameplay is currently active. + /// + public readonly Bindable IsGameplay = new BindableBool(); + protected OsuScreenStack ScreenStack; protected BackButton BackButton; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 175722c44e..a217d2a396 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -68,6 +68,8 @@ namespace osu.Game.Screens.Play private readonly Bindable storyboardReplacesBackground = new Bindable(); + private readonly Bindable isGameplay = new Bindable(); + public int RestartCount; [Resolved] @@ -156,7 +158,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config) + private void load(AudioManager audio, OsuConfigManager config, OsuGame game) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -172,6 +174,8 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + isGameplay.BindTo(game.IsGameplay); + DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); ScoreProcessor = ruleset.CreateScoreProcessor(); @@ -219,9 +223,9 @@ namespace osu.Game.Screens.Play skipOverlay.Hide(); } - DrawableRuleset.IsPaused.BindValueChanged(_ => updateOverlayActivationMode()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateOverlayActivationMode()); - breakTracker.IsBreakTime.BindValueChanged(_ => updateOverlayActivationMode()); + DrawableRuleset.IsPaused.BindValueChanged(_ => updateGameplayState()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState()); + breakTracker.IsBreakTime.BindValueChanged(_ => updateGameplayState()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); @@ -353,14 +357,11 @@ namespace osu.Game.Screens.Play HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue; } - private void updateOverlayActivationMode() + private void updateGameplayState() { - bool canTriggerOverlays = DrawableRuleset.IsPaused.Value || breakTracker.IsBreakTime.Value; - - if (DrawableRuleset.HasReplayLoaded.Value || canTriggerOverlays) - OverlayActivationMode.Value = OverlayActivation.UserTriggered; - else - OverlayActivationMode.Value = OverlayActivation.Disabled; + bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value; + OverlayActivationMode.Value = inGameplay ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + isGameplay.Value = inGameplay; } private void updatePauseOnFocusLostState() => @@ -657,7 +658,7 @@ namespace osu.Game.Screens.Play foreach (var mod in Mods.Value.OfType()) mod.ApplyToTrack(musicController.CurrentTrack); - updateOverlayActivationMode(); + updateGameplayState(); } public override void OnSuspending(IScreen next) @@ -693,6 +694,9 @@ namespace osu.Game.Screens.Play musicController.ResetTrackAdjustments(); + // Ensure we reset the IsGameplay state + isGameplay.Value = false; + fadeOut(); return base.OnExiting(next); } From 14c734c24407d7e8250ccf8dcba113065c37d623 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 21:21:09 +0900 Subject: [PATCH 37/62] Add a very simple method of applying batch changes to EditorBeatmap --- osu.Game/Screens/Edit/EditorBeatmap.cs | 69 ++++++++++++++++--- .../Edit/LegacyEditorBeatmapPatcher.cs | 21 +++--- 2 files changed, 73 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 3248c5b8be..549423dfb8 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -91,6 +91,8 @@ namespace osu.Game.Screens.Edit private readonly HashSet pendingUpdates = new HashSet(); + private bool isBatchApplying; + /// /// Adds a collection of s to this . /// @@ -126,12 +128,17 @@ namespace osu.Game.Screens.Edit mutableHitObjects.Insert(index, hitObject); - // must be run after any change to hitobject ordering - beatmapProcessor?.PreProcess(); - processHitObject(hitObject); - beatmapProcessor?.PostProcess(); + if (isBatchApplying) + batchPendingInserts.Add(hitObject); + else + { + // must be run after any change to hitobject ordering + beatmapProcessor?.PreProcess(); + processHitObject(hitObject); + beatmapProcessor?.PostProcess(); - HitObjectAdded?.Invoke(hitObject); + HitObjectAdded?.Invoke(hitObject); + } } /// @@ -180,12 +187,58 @@ namespace osu.Game.Screens.Edit bindable.UnbindAll(); startTimeBindables.Remove(hitObject); - // must be run after any change to hitobject ordering + if (isBatchApplying) + batchPendingDeletes.Add(hitObject); + else + { + // must be run after any change to hitobject ordering + beatmapProcessor?.PreProcess(); + processHitObject(hitObject); + beatmapProcessor?.PostProcess(); + + HitObjectRemoved?.Invoke(hitObject); + } + } + + private readonly List batchPendingInserts = new List(); + + private readonly List batchPendingDeletes = new List(); + + /// + /// Apply a batch of operations in one go, without performing Pre/Postprocessing each time. + /// + /// The function which will apply the batch changes. + public void ApplyBatchChanges(Action applyFunction) + { + if (isBatchApplying) + throw new InvalidOperationException("Attempting to perform a batch application from within an existing batch"); + + isBatchApplying = true; + + applyFunction(this); + beatmapProcessor?.PreProcess(); - processHitObject(hitObject); beatmapProcessor?.PostProcess(); - HitObjectRemoved?.Invoke(hitObject); + isBatchApplying = false; + + foreach (var h in batchPendingDeletes) + { + processHitObject(h); + HitObjectRemoved?.Invoke(h); + } + + batchPendingDeletes.Clear(); + + foreach (var h in batchPendingInserts) + { + processHitObject(h); + HitObjectAdded?.Invoke(h); + } + + batchPendingInserts.Clear(); + + isBatchApplying = false; } /// diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index 57b7ce6940..fb7d0dd826 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -68,16 +68,19 @@ namespace osu.Game.Screens.Edit toRemove.Sort(); toAdd.Sort(); - // Apply the changes. - for (int i = toRemove.Count - 1; i >= 0; i--) - editorBeatmap.RemoveAt(toRemove[i]); - - if (toAdd.Count > 0) + editorBeatmap.ApplyBatchChanges(eb => { - IBeatmap newBeatmap = readBeatmap(newState); - foreach (var i in toAdd) - editorBeatmap.Insert(i, newBeatmap.HitObjects[i]); - } + // Apply the changes. + for (int i = toRemove.Count - 1; i >= 0; i--) + eb.RemoveAt(toRemove[i]); + + if (toAdd.Count > 0) + { + IBeatmap newBeatmap = readBeatmap(newState); + foreach (var i in toAdd) + eb.Insert(i, newBeatmap.HitObjects[i]); + } + }); } private string readString(byte[] state) => Encoding.UTF8.GetString(state); From 09f5e9c9eb545bdc8880a6362e1de61f39077fb9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 22:09:48 +0900 Subject: [PATCH 38/62] Use batch change application in many places that can benefit from it --- .../Compose/Components/SelectionHandler.cs | 5 +--- osu.Game/Screens/Edit/Editor.cs | 3 +- osu.Game/Screens/Edit/EditorBeatmap.cs | 28 +++++++++++++------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index fdf8dbe44e..7808d7a5bc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -239,10 +239,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void deleteSelected() { ChangeHandler?.BeginChange(); - - foreach (var h in selectedBlueprints.ToList()) - EditorBeatmap?.Remove(h.HitObject); - + EditorBeatmap?.RemoveRange(selectedBlueprints.Select(b => b.HitObject)); ChangeHandler?.EndChange(); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 4b4266d049..3c5cbf30e9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -484,8 +484,7 @@ namespace osu.Game.Screens.Edit protected void Cut() { Copy(); - foreach (var h in editorBeatmap.SelectedHitObjects.ToArray()) - editorBeatmap.Remove(h); + editorBeatmap.RemoveRange(editorBeatmap.SelectedHitObjects.ToArray()); } protected void Copy() diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 549423dfb8..1357f12055 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -99,8 +99,11 @@ namespace osu.Game.Screens.Edit /// The s to add. public void AddRange(IEnumerable hitObjects) { - foreach (var h in hitObjects) - Add(h); + ApplyBatchChanges(_ => + { + foreach (var h in hitObjects) + Add(h); + }); } /// @@ -166,6 +169,19 @@ namespace osu.Game.Screens.Edit return true; } + /// + /// Removes a collection of s to this . + /// + /// The s to remove. + public void RemoveRange(IEnumerable hitObjects) + { + ApplyBatchChanges(_ => + { + foreach (var h in hitObjects) + Remove(h); + }); + } + /// /// Finds the index of a in this . /// @@ -237,18 +253,12 @@ namespace osu.Game.Screens.Edit } batchPendingInserts.Clear(); - - isBatchApplying = false; } /// /// Clears all from this . /// - public void Clear() - { - foreach (var h in HitObjects.ToArray()) - Remove(h); - } + public void Clear() => RemoveRange(HitObjects.ToArray()); protected override void Update() { From afe3d3989a08a4e6aa0e8d88cc01d7cff78e40ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:04:50 +0900 Subject: [PATCH 39/62] Force first hitobject to be a NewCombo in BeatmapProcessor preprocessing step --- osu.Game/Beatmaps/BeatmapProcessor.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index 250cc49ad4..b7b5adc52e 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -22,8 +22,18 @@ namespace osu.Game.Beatmaps { IHasComboInformation lastObj = null; + bool isFirst = true; + foreach (var obj in Beatmap.HitObjects.OfType()) { + if (isFirst) + { + obj.NewCombo = true; + + // first hitobject should always be marked as a new combo for sanity. + isFirst = false; + } + if (obj.NewCombo) { obj.IndexInCurrentCombo = 0; From 1f2dd13b49ccaeb572150b159bac8420c22f2dd4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Oct 2020 19:04:58 +0900 Subject: [PATCH 40/62] Update tests --- .../Editing/LegacyEditorBeatmapPatcherTest.cs | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index b491157627..afaaafdd26 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Editing { HitObjects = { - new HitCircle { StartTime = 1000 } + new HitCircle { StartTime = 1000, NewCombo = true } } }; @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new HitCircle { StartTime = 3000 }, }); @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new HitCircle { StartTime = 2000 }, new HitCircle { StartTime = 3000 }, }); @@ -100,7 +100,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new HitCircle { StartTime = 2000 }, new HitCircle { StartTime = 3000 }, }); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Editing { HitObjects = { - new HitCircle { StartTime = 500 }, + new HitCircle { StartTime = 500, NewCombo = true }, (OsuHitObject)current.HitObjects[1], (OsuHitObject)current.HitObjects[2], } @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new HitCircle { StartTime = 2000 }, new HitCircle { StartTime = 3000 }, }); @@ -146,7 +146,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new OsuHitObject[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new Slider { StartTime = 2000, @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 1000, NewCombo = true }, new HitCircle { StartTime = 2000 }, new HitCircle { StartTime = 3000 }, }); @@ -197,7 +197,7 @@ namespace osu.Game.Tests.Editing { HitObjects = { - new HitCircle { StartTime = 500 }, + new HitCircle { StartTime = 500, NewCombo = true }, (OsuHitObject)current.HitObjects[0], new HitCircle { StartTime = 1500 }, (OsuHitObject)current.HitObjects[1], @@ -216,7 +216,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 500 }, + new HitCircle { StartTime = 500, NewCombo = true }, new HitCircle { StartTime = 1000 }, new HitCircle { StartTime = 1500 }, new HitCircle { StartTime = 2000 }, @@ -226,6 +226,9 @@ namespace osu.Game.Tests.Editing new HitCircle { StartTime = 3500 }, }); + var patchedFirst = (HitCircle)current.HitObjects[1]; + patchedFirst.NewCombo = true; + var patch = new OsuBeatmap { HitObjects = @@ -244,7 +247,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 500 }, + new HitCircle { StartTime = 500, NewCombo = true }, new HitCircle { StartTime = 1000 }, new HitCircle { StartTime = 1500 }, new HitCircle { StartTime = 2000 }, @@ -277,7 +280,7 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 500 }, + new HitCircle { StartTime = 500, NewCombo = true }, new HitCircle { StartTime = 1000 }, new HitCircle { StartTime = 1500 }, new HitCircle { StartTime = 2000 }, @@ -291,7 +294,7 @@ namespace osu.Game.Tests.Editing { HitObjects = { - new HitCircle { StartTime = 750 }, + new HitCircle { StartTime = 750, NewCombo = true }, (OsuHitObject)current.HitObjects[1], (OsuHitObject)current.HitObjects[4], (OsuHitObject)current.HitObjects[5], @@ -309,20 +312,20 @@ namespace osu.Game.Tests.Editing { current.AddRange(new[] { - new HitCircle { StartTime = 500, Position = new Vector2(50) }, - new HitCircle { StartTime = 500, Position = new Vector2(100) }, - new HitCircle { StartTime = 500, Position = new Vector2(150) }, - new HitCircle { StartTime = 500, Position = new Vector2(200) }, + new HitCircle { StartTime = 500, Position = new Vector2(50), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(100), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(150), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(200), NewCombo = true }, }); var patch = new OsuBeatmap { HitObjects = { - new HitCircle { StartTime = 500, Position = new Vector2(150) }, - new HitCircle { StartTime = 500, Position = new Vector2(100) }, - new HitCircle { StartTime = 500, Position = new Vector2(50) }, - new HitCircle { StartTime = 500, Position = new Vector2(200) }, + new HitCircle { StartTime = 500, Position = new Vector2(150), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(100), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(50), NewCombo = true }, + new HitCircle { StartTime = 500, Position = new Vector2(200), NewCombo = true }, } }; From f5a6beb4e55f17407640c32f85cd21d1baf86284 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 6 Oct 2020 19:01:03 +0200 Subject: [PATCH 41/62] Remove obsoletion notice. --- osu.Game/Rulesets/Ruleset.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 2ba884efc2..ae1407fb8f 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -160,7 +160,6 @@ namespace osu.Game.Rulesets public virtual PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => null; - [Obsolete("Use the DifficultyAttributes overload instead.")] public PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) { var difficultyCalculator = CreateDifficultyCalculator(beatmap); From 8847b88e653490a62d5319bc066702d9151d100c Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 11:44:41 +1030 Subject: [PATCH 42/62] Fix unit tests trying to resolve OsuGame --- osu.Game/Screens/Play/Player.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a217d2a396..932c5ba1df 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, OsuGame game) + private void load(AudioManager audio, OsuConfigManager config, OsuGameBase game) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -174,7 +174,8 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - isGameplay.BindTo(game.IsGameplay); + if (game is OsuGame osuGame) + isGameplay.BindTo(osuGame.IsGameplay); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); From c1a8fe01ef6a5253e060fa1db27cbb730882c4a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 11:09:45 +0900 Subject: [PATCH 43/62] Fix postprocess order in batch events --- osu.Game/Screens/Edit/EditorBeatmap.cs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 1357f12055..be032d3104 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -234,25 +234,19 @@ namespace osu.Game.Screens.Edit applyFunction(this); beatmapProcessor?.PreProcess(); + + foreach (var h in batchPendingDeletes) processHitObject(h); + foreach (var h in batchPendingInserts) processHitObject(h); + beatmapProcessor?.PostProcess(); - isBatchApplying = false; - - foreach (var h in batchPendingDeletes) - { - processHitObject(h); - HitObjectRemoved?.Invoke(h); - } + foreach (var h in batchPendingDeletes) HitObjectRemoved?.Invoke(h); + foreach (var h in batchPendingInserts) HitObjectAdded?.Invoke(h); batchPendingDeletes.Clear(); - - foreach (var h in batchPendingInserts) - { - processHitObject(h); - HitObjectAdded?.Invoke(h); - } - batchPendingInserts.Clear(); + + isBatchApplying = false; } /// From a8151d5c635c0803dc9fc5812904156ce49b405e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 13:45:41 +0900 Subject: [PATCH 44/62] Fix HitWindows getting serialized alongside HitObjects These were being serialized as the base type. On deserialization, due to the HitWindow of objects being non-null, they would not get correctly initialised by the CreateHitWindows() virtual method. - Closes #10403 --- osu.Game/Rulesets/Objects/HitObject.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 0dfde834ee..826d411822 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -77,6 +77,7 @@ namespace osu.Game.Rulesets.Objects /// /// The hit windows for this . /// + [JsonIgnore] public HitWindows HitWindows { get; set; } private readonly List nestedHitObjects = new List(); From a6d1484ad5af2f5eb921133a283477b235da0d56 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 14:26:01 +0900 Subject: [PATCH 45/62] Add arbirary precision specification for now --- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index f23bc0f3b2..2d8031c3c8 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -38,7 +38,8 @@ namespace osu.Game.Screens.Edit.Setup { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, MinValue = 2, - MaxValue = 7 + MaxValue = 7, + Precision = 0.1f, } }, healthDrainSlider = new LabelledSliderBar @@ -49,7 +50,8 @@ namespace osu.Game.Screens.Edit.Setup { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, MinValue = 0, - MaxValue = 10 + MaxValue = 10, + Precision = 0.1f, } }, approachRateSlider = new LabelledSliderBar @@ -60,7 +62,8 @@ namespace osu.Game.Screens.Edit.Setup { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, MinValue = 0, - MaxValue = 10 + MaxValue = 10, + Precision = 0.1f, } }, overallDifficultySlider = new LabelledSliderBar @@ -71,7 +74,8 @@ namespace osu.Game.Screens.Edit.Setup { Default = BeatmapDifficulty.DEFAULT_DIFFICULTY, MinValue = 0, - MaxValue = 10 + MaxValue = 10, + Precision = 0.1f, } }, }; From c8c5998af475a9860041eea732e61a10f949f069 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 16:02:35 +1030 Subject: [PATCH 46/62] Bail if FrameworkSetting.ConfineMouseMode is unavailable --- osu.Game/Input/ConfineMouseTracker.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index c1089874ae..3d16e44607 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -34,6 +34,10 @@ namespace osu.Game.Input private void updateConfineMode() { + // confine mode is unavailable on some platforms + if (frameworkConfineMode.Disabled) + return; + switch (osuConfineMode.Value) { case OsuConfineMouseMode.Never: From 7fff762dfc91222fe1823f3b73f90aa588b5129c Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 16:14:49 +1030 Subject: [PATCH 47/62] Rename IsGameplay --- osu.Game/Input/ConfineMouseTracker.cs | 10 +++++----- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 3d16e44607..3dadae6317 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -12,24 +12,24 @@ namespace osu.Game.Input { /// /// Connects with . - /// If is true, we should also confine the mouse cursor if it has been + /// If is true, we should also confine the mouse cursor if it has been /// requested with . /// public class ConfineMouseTracker : Component { private Bindable frameworkConfineMode; private Bindable osuConfineMode; - private IBindable isGameplay; + private IBindable localUserPlaying; [BackgroundDependencyLoader] private void load(OsuGame game, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) { frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); - isGameplay = game.IsGameplay.GetBoundCopy(); + localUserPlaying = game.LocalUserPlaying.GetBoundCopy(); osuConfineMode.ValueChanged += _ => updateConfineMode(); - isGameplay.BindValueChanged(_ => updateConfineMode(), true); + localUserPlaying.BindValueChanged(_ => updateConfineMode(), true); } private void updateConfineMode() @@ -49,7 +49,7 @@ namespace osu.Game.Input break; case OsuConfineMouseMode.DuringGameplay: - frameworkConfineMode.Value = isGameplay.Value ? ConfineMouseMode.Always : ConfineMouseMode.Never; + frameworkConfineMode.Value = localUserPlaying.Value ? ConfineMouseMode.Always : ConfineMouseMode.Never; break; case OsuConfineMouseMode.Always: diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 466ff13615..c09ad0eeb9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -98,9 +98,9 @@ namespace osu.Game public readonly IBindable OverlayActivationMode = new Bindable(); /// - /// Whether gameplay is currently active. + /// Whether the local user is currently interacting with the game in a way that should not be interrupted. /// - public readonly Bindable IsGameplay = new BindableBool(); + public readonly Bindable LocalUserPlaying = new BindableBool(); protected OsuScreenStack ScreenStack; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 932c5ba1df..e6c15521af 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play private readonly Bindable storyboardReplacesBackground = new Bindable(); - private readonly Bindable isGameplay = new Bindable(); + private readonly Bindable localUserPlaying = new Bindable(); public int RestartCount; @@ -175,7 +175,7 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); if (game is OsuGame osuGame) - isGameplay.BindTo(osuGame.IsGameplay); + localUserPlaying.BindTo(osuGame.LocalUserPlaying); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); @@ -362,7 +362,7 @@ namespace osu.Game.Screens.Play { bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value; OverlayActivationMode.Value = inGameplay ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; - isGameplay.Value = inGameplay; + localUserPlaying.Value = inGameplay; } private void updatePauseOnFocusLostState() => @@ -695,8 +695,8 @@ namespace osu.Game.Screens.Play musicController.ResetTrackAdjustments(); - // Ensure we reset the IsGameplay state - isGameplay.Value = false; + // Ensure we reset the LocalUserPlaying state + localUserPlaying.Value = false; fadeOut(); return base.OnExiting(next); From 485bd962c7d52d738547af4bcd43af535e2e935a Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 16:15:17 +1030 Subject: [PATCH 48/62] Also reset LocalUserPlaying in OnSuspending --- osu.Game/Screens/Play/Player.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e6c15521af..43dce0786d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -666,6 +666,9 @@ namespace osu.Game.Screens.Play { screenSuspension?.Expire(); + // Ensure we reset the LocalUserPlaying state + localUserPlaying.Value = false; + fadeOut(); base.OnSuspending(next); } From d1ec3806927a3bb042e47b76be921582ed87575e Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 16:15:32 +1030 Subject: [PATCH 49/62] Don't cache ConfineMouseTracker --- osu.Game/OsuGame.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c09ad0eeb9..d22ac1aec8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -549,7 +549,6 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); - dependencies.Cache(confineMouseTracker = new ConfineMouseTracker()); AddRange(new Drawable[] { @@ -586,7 +585,7 @@ namespace osu.Game leftFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, topMostOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, idleTracker, - confineMouseTracker + confineMouseTracker = new ConfineMouseTracker() }); ScreenStack.ScreenPushed += screenPushed; From 8b8eb00bd75c4790bec72bdd8a79f5e6ddddf457 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 16:16:58 +1030 Subject: [PATCH 50/62] Permit nulls rather than casting to OsuGame --- osu.Game/Screens/Play/Player.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 43dce0786d..39a6ac4ded 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -157,8 +157,8 @@ namespace osu.Game.Screens.Play DrawableRuleset.SetRecordTarget(recordingReplay = new Replay()); } - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, OsuGameBase game) + [BackgroundDependencyLoader(true)] + private void load(AudioManager audio, OsuConfigManager config, OsuGame game) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); @@ -174,8 +174,8 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - if (game is OsuGame osuGame) - localUserPlaying.BindTo(osuGame.LocalUserPlaying); + if (game != null) + localUserPlaying.BindTo(game.LocalUserPlaying); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); From 2e0a9f53c11a4d1e4fe2b63e22a3af3de579904d Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 17:52:39 +1030 Subject: [PATCH 51/62] Add test coverage --- .../Visual/Gameplay/TestSceneOverlayActivation.cs | 10 ++++++++++ osu.Game/Screens/Play/Player.cs | 10 +++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index ce04b940e7..41f7582d31 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -3,6 +3,7 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Bindables; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -23,32 +24,40 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestGameplayOverlayActivation() { + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); } [Test] public void TestGameplayOverlayActivationPaused() { + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("pause gameplay", () => Player.Pause()); + AddAssert("local user not playing", () => !Player.LocalUserPlaying.Value); AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); } [Test] public void TestGameplayOverlayActivationReplayLoaded() { + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("load a replay", () => Player.DrawableRuleset.HasReplayLoaded.Value = true); + AddAssert("local user not playing", () => !Player.LocalUserPlaying.Value); AddAssert("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); } [Test] public void TestGameplayOverlayActivationBreaks() { + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("seek to break", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); + AddAssert("local user not playing", () => !Player.LocalUserPlaying.Value); AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); AddStep("seek to break end", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().EndTime)); + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddUntilStep("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); } @@ -57,6 +66,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected class OverlayTestPlayer : TestPlayer { public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value; + public new Bindable LocalUserPlaying => base.LocalUserPlaying; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 39a6ac4ded..8830884a40 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Play private readonly Bindable storyboardReplacesBackground = new Bindable(); - private readonly Bindable localUserPlaying = new Bindable(); + protected readonly Bindable LocalUserPlaying = new Bindable(); public int RestartCount; @@ -175,7 +175,7 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); if (game != null) - localUserPlaying.BindTo(game.LocalUserPlaying); + LocalUserPlaying.BindTo(game.LocalUserPlaying); DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); @@ -362,7 +362,7 @@ namespace osu.Game.Screens.Play { bool inGameplay = !DrawableRuleset.HasReplayLoaded.Value && !DrawableRuleset.IsPaused.Value && !breakTracker.IsBreakTime.Value; OverlayActivationMode.Value = inGameplay ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; - localUserPlaying.Value = inGameplay; + LocalUserPlaying.Value = inGameplay; } private void updatePauseOnFocusLostState() => @@ -667,7 +667,7 @@ namespace osu.Game.Screens.Play screenSuspension?.Expire(); // Ensure we reset the LocalUserPlaying state - localUserPlaying.Value = false; + LocalUserPlaying.Value = false; fadeOut(); base.OnSuspending(next); @@ -699,7 +699,7 @@ namespace osu.Game.Screens.Play musicController.ResetTrackAdjustments(); // Ensure we reset the LocalUserPlaying state - localUserPlaying.Value = false; + LocalUserPlaying.Value = false; fadeOut(); return base.OnExiting(next); From f88ba1734bd6cc687d86de8a2a02a87d386dbbb9 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 18:11:47 +1030 Subject: [PATCH 52/62] Remove ConfineMouseTracker field --- osu.Game/OsuGame.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d22ac1aec8..772f9ff145 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -90,8 +90,6 @@ namespace osu.Game private IdleTracker idleTracker; - private ConfineMouseTracker confineMouseTracker; - /// /// Whether overlays should be able to be opened game-wide. Value is sourced from the current active screen. /// @@ -585,7 +583,7 @@ namespace osu.Game leftFloatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, topMostOverlayContent = new Container { RelativeSizeAxes = Axes.Both }, idleTracker, - confineMouseTracker = new ConfineMouseTracker() + new ConfineMouseTracker() }); ScreenStack.ScreenPushed += screenPushed; From f90ac2e76c2bf20c88fafef834b3c9110156f660 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 7 Oct 2020 18:50:02 +1030 Subject: [PATCH 53/62] Ensure we assert after the seek has completed --- osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 41f7582d31..4fa4c00981 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -54,11 +54,11 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddAssert("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); AddStep("seek to break", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().StartTime)); - AddAssert("local user not playing", () => !Player.LocalUserPlaying.Value); AddUntilStep("activation mode is user triggered", () => Player.OverlayActivationMode == OverlayActivation.UserTriggered); + AddAssert("local user not playing", () => !Player.LocalUserPlaying.Value); AddStep("seek to break end", () => Player.GameplayClockContainer.Seek(Beatmap.Value.Beatmap.Breaks.First().EndTime)); - AddAssert("local user playing", () => Player.LocalUserPlaying.Value); AddUntilStep("activation mode is disabled", () => Player.OverlayActivationMode == OverlayActivation.Disabled); + AddAssert("local user playing", () => Player.LocalUserPlaying.Value); } protected override TestPlayer CreatePlayer(Ruleset ruleset) => new OverlayTestPlayer(); From 0f6eb9d4cb7750c1890da24f26d5080f42e643ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 17:40:54 +0900 Subject: [PATCH 54/62] Ensure music playback is stopped when retrying by any means --- osu.Game/Screens/Play/Player.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 175722c44e..90a0eb0027 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -441,6 +441,10 @@ namespace osu.Game.Screens.Play /// public void Restart() { + // at the point of restarting the track should either already be paused or the volume should be zero. + // stopping here is to ensure music doesn't become audible after exiting back to PlayerLoader. + musicController.Stop(); + sampleRestart?.Play(); RestartRequested?.Invoke(); From 04fa0bff9d8c6bbb2d1b656619a103c7e17d4211 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 17:46:57 +0900 Subject: [PATCH 55/62] Add CanBeNull spec and xmldoc --- osu.Game/Rulesets/Ruleset.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ae1407fb8f..fef36ef16a 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -158,8 +158,22 @@ namespace osu.Game.Rulesets public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); + /// + /// Optionally creates a to generate performance data from the provided score. + /// + /// Difficulty attributes for the beatmap related to the provided score. + /// The score to be processed. + /// A performance calculator instance for the provided score. + [CanBeNull] public virtual PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => null; + /// + /// Optionally creates a to generate performance data from the provided score. + /// + /// The beatmap to use as a source for generating . + /// The score to be processed. + /// A performance calculator instance for the provided score. + [CanBeNull] public PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) { var difficultyCalculator = CreateDifficultyCalculator(beatmap); From 3c3c1ce8855487356f0c6afec1fc6b25d70542c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 18:18:01 +0900 Subject: [PATCH 56/62] Don't force playback of (non-looping) DrawableHitObject samples after skin change --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 8012b4d95c..1ef6c8c207 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Objects.Drawables // apply any custom state overrides ApplyCustomUpdateState?.Invoke(this, newState); - if (newState == ArmedState.Hit) + if (!force && newState == ArmedState.Hit) PlaySamples(); } From 8c528c89108ca7a7ffde30f2a355f214205e3e88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Oct 2020 18:36:34 +0900 Subject: [PATCH 57/62] Fix legacy taiko skins showing double judgements --- .../Skinning/TaikoLegacySkinTransformer.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs index 93c9deec1f..a804ea5f82 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Audio; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Skinning; @@ -14,13 +15,29 @@ namespace osu.Game.Rulesets.Taiko.Skinning { public class TaikoLegacySkinTransformer : LegacySkinTransformer { + private Lazy hasExplosion; + public TaikoLegacySkinTransformer(ISkinSource source) : base(source) { + Source.SourceChanged += sourceChanged; + sourceChanged(); + } + + private void sourceChanged() + { + hasExplosion = new Lazy(() => Source.GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null); } public override Drawable GetDrawableComponent(ISkinComponent component) { + if (component is GameplaySkinComponent) + { + // if a taiko skin is providing explosion sprites, hide the judgements completely + if (hasExplosion.Value) + return Drawable.Empty(); + } + if (!(component is TaikoSkinComponent taikoComponent)) return null; @@ -87,10 +104,13 @@ namespace osu.Game.Rulesets.Taiko.Skinning var hitName = getHitName(taikoComponent.Component); var hitSprite = this.GetAnimation(hitName, true, false); - var strongHitSprite = this.GetAnimation($"{hitName}k", true, false); if (hitSprite != null) + { + var strongHitSprite = this.GetAnimation($"{hitName}k", true, false); + return new LegacyHitExplosion(hitSprite, strongHitSprite); + } return null; From b1029a124ca6efd53a24a950d290c33f5efed148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 7 Oct 2020 22:57:20 +0200 Subject: [PATCH 58/62] Move event subscription to LoadComplete Prevents attempting to read from the `colours` field before it is actually injected. --- osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 4121e1f7bb..c8982b819a 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -113,7 +113,6 @@ namespace osu.Game.Screens.Edit.Timing }; controlPoints = group.ControlPoints.GetBoundCopy(); - controlPoints.CollectionChanged += (_, __) => createChildren(); } [Resolved] @@ -125,6 +124,12 @@ namespace osu.Game.Screens.Edit.Timing createChildren(); } + protected override void LoadComplete() + { + base.LoadComplete(); + controlPoints.CollectionChanged += (_, __) => createChildren(); + } + private void createChildren() { fill.ChildrenEnumerable = controlPoints.Select(createAttribute).Where(c => c != null); From ac44f6f679504554485edb3877f76615f463f1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 7 Oct 2020 23:10:28 +0200 Subject: [PATCH 59/62] Ensure control point group exists after move If the control point group moved was empty, it would not be created due to a lack of ControlPointInfo.Add() calls. --- osu.Game/Screens/Edit/Timing/GroupSection.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/GroupSection.cs b/osu.Game/Screens/Edit/Timing/GroupSection.cs index c77d48ef0a..d76b5e7406 100644 --- a/osu.Game/Screens/Edit/Timing/GroupSection.cs +++ b/osu.Game/Screens/Edit/Timing/GroupSection.cs @@ -111,7 +111,8 @@ namespace osu.Game.Screens.Edit.Timing foreach (var cp in currentGroupItems) Beatmap.Value.Beatmap.ControlPointInfo.Add(time, cp); - SelectedGroup.Value = Beatmap.Value.Beatmap.ControlPointInfo.GroupAt(time); + // the control point might not necessarily exist yet, if currentGroupItems was empty. + SelectedGroup.Value = Beatmap.Value.Beatmap.ControlPointInfo.GroupAt(time, true); changeHandler?.EndChange(); } From 0967db768ffb922e0d6e46fe71ada6bf94731533 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Oct 2020 18:25:40 +0900 Subject: [PATCH 60/62] Add xmldoc covering usage restrictions --- osu.Game/OsuGame.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 772f9ff145..e6f6d526cf 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -98,7 +98,11 @@ namespace osu.Game /// /// Whether the local user is currently interacting with the game in a way that should not be interrupted. /// - public readonly Bindable LocalUserPlaying = new BindableBool(); + /// + /// This is exclusively managed by . If other components are mutating this state, a more + /// resilient method should be used to ensure correct state. + /// + public Bindable LocalUserPlaying = new BindableBool(); protected OsuScreenStack ScreenStack; From 43a575484ad1440a799aa41433840b47f5299f1e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Oct 2020 18:25:43 +0900 Subject: [PATCH 61/62] Remove pointless comments --- osu.Game/Screens/Play/Player.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8830884a40..80dd8ae92c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -666,7 +666,6 @@ namespace osu.Game.Screens.Play { screenSuspension?.Expire(); - // Ensure we reset the LocalUserPlaying state LocalUserPlaying.Value = false; fadeOut(); @@ -698,7 +697,6 @@ namespace osu.Game.Screens.Play musicController.ResetTrackAdjustments(); - // Ensure we reset the LocalUserPlaying state LocalUserPlaying.Value = false; fadeOut(); From dbdb25ccf756cf48ec3ecff87a81aec86f0f0224 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Oct 2020 18:29:19 +0900 Subject: [PATCH 62/62] Move reset logic to OsuGame --- osu.Game/OsuGame.cs | 3 +++ osu.Game/Screens/Play/Player.cs | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e6f6d526cf..d315b213ab 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -957,6 +957,9 @@ namespace osu.Game break; } + // reset on screen change for sanity. + LocalUserPlaying.Value = false; + if (current is IOsuScreen currentOsuScreen) OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 80dd8ae92c..45f194fc29 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -666,8 +666,6 @@ namespace osu.Game.Screens.Play { screenSuspension?.Expire(); - LocalUserPlaying.Value = false; - fadeOut(); base.OnSuspending(next); } @@ -697,8 +695,6 @@ namespace osu.Game.Screens.Play musicController.ResetTrackAdjustments(); - LocalUserPlaying.Value = false; - fadeOut(); return base.OnExiting(next); }