mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 06:33:20 +08:00
Merge pull request #19783 from bdach/mod-select/presets-dont-open-customisation
Fix selecting preset containing Difficulty Adjust automatically opening customisation panel
This commit is contained in:
commit
0815b01b75
@ -1,14 +1,13 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -29,10 +28,18 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneModSelectOverlay : OsuManualInputManagerTestScene
|
public class TestSceneModSelectOverlay : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
protected override bool UseFreshStoragePerRun => true;
|
||||||
private RulesetStore rulesetStore { get; set; }
|
|
||||||
|
|
||||||
private UserModSelectOverlay modSelectOverlay;
|
private RulesetStore rulesetStore = null!;
|
||||||
|
|
||||||
|
private TestModSelectOverlay modSelectOverlay = null!;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Dependencies.Cache(rulesetStore = new RealmRulesetStore(Realm));
|
||||||
|
Dependencies.Cache(Realm);
|
||||||
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
@ -40,11 +47,31 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("clear contents", Clear);
|
AddStep("clear contents", Clear);
|
||||||
AddStep("reset ruleset", () => Ruleset.Value = rulesetStore.GetRuleset(0));
|
AddStep("reset ruleset", () => Ruleset.Value = rulesetStore.GetRuleset(0));
|
||||||
AddStep("reset mods", () => SelectedMods.SetDefault());
|
AddStep("reset mods", () => SelectedMods.SetDefault());
|
||||||
|
AddStep("set up presets", () =>
|
||||||
|
{
|
||||||
|
Realm.Write(r =>
|
||||||
|
{
|
||||||
|
r.RemoveAll<ModPreset>();
|
||||||
|
r.Add(new ModPreset
|
||||||
|
{
|
||||||
|
Name = "AR0",
|
||||||
|
Description = "Too... many... circles...",
|
||||||
|
Ruleset = r.Find<RulesetInfo>(OsuRuleset.SHORT_NAME),
|
||||||
|
Mods = new[]
|
||||||
|
{
|
||||||
|
new OsuModDifficultyAdjust
|
||||||
|
{
|
||||||
|
ApproachRate = { Value = 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createScreen()
|
private void createScreen()
|
||||||
{
|
{
|
||||||
AddStep("create screen", () => Child = modSelectOverlay = new UserModSelectOverlay
|
AddStep("create screen", () => Child = modSelectOverlay = new TestModSelectOverlay
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
State = { Value = Visibility.Visible },
|
State = { Value = Visibility.Visible },
|
||||||
@ -137,7 +164,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
||||||
|
|
||||||
ModSelectColumn lastColumn = null;
|
ModSelectColumn lastColumn = null!;
|
||||||
|
|
||||||
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
|
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
|
||||||
AddStep("request scroll to last column", () =>
|
AddStep("request scroll to last column", () =>
|
||||||
@ -165,18 +192,22 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("select customisable mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() });
|
AddStep("select customisable mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() });
|
||||||
assertCustomisationToggleState(disabled: false, active: false);
|
assertCustomisationToggleState(disabled: false, active: false);
|
||||||
|
|
||||||
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
AddStep("select mod requiring configuration externally", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
||||||
|
assertCustomisationToggleState(disabled: false, active: false);
|
||||||
|
|
||||||
|
AddStep("reset mods", () => SelectedMods.SetDefault());
|
||||||
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
assertCustomisationToggleState(disabled: false, active: true);
|
assertCustomisationToggleState(disabled: false, active: true);
|
||||||
|
|
||||||
AddStep("dismiss mod customisation via toggle", () =>
|
AddStep("dismiss mod customisation via toggle", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(modSelectOverlay.ChildrenOfType<ShearedToggleButton>().Single());
|
InputManager.MoveMouseTo(modSelectOverlay.CustomisationButton);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
assertCustomisationToggleState(disabled: false, active: false);
|
assertCustomisationToggleState(disabled: false, active: false);
|
||||||
|
|
||||||
AddStep("reset mods", () => SelectedMods.SetDefault());
|
AddStep("reset mods", () => SelectedMods.SetDefault());
|
||||||
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
assertCustomisationToggleState(disabled: false, active: true);
|
assertCustomisationToggleState(disabled: false, active: true);
|
||||||
|
|
||||||
AddStep("dismiss mod customisation via keyboard", () => InputManager.Key(Key.Escape));
|
AddStep("dismiss mod customisation via keyboard", () => InputManager.Key(Key.Escape));
|
||||||
@ -188,11 +219,18 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
||||||
assertCustomisationToggleState(disabled: true, active: false);
|
assertCustomisationToggleState(disabled: true, active: false);
|
||||||
|
|
||||||
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
assertCustomisationToggleState(disabled: false, active: true);
|
assertCustomisationToggleState(disabled: false, active: true);
|
||||||
|
|
||||||
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
||||||
assertCustomisationToggleState(disabled: true, active: false); // config was dismissed without explicit user action.
|
assertCustomisationToggleState(disabled: true, active: false); // config was dismissed without explicit user action.
|
||||||
|
|
||||||
|
AddStep("select mod preset with mod requiring configuration", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(this.ChildrenOfType<ModPresetPanel>().First());
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
assertCustomisationToggleState(disabled: false, active: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -201,7 +239,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
createScreen();
|
createScreen();
|
||||||
assertCustomisationToggleState(disabled: true, active: false);
|
assertCustomisationToggleState(disabled: true, active: false);
|
||||||
|
|
||||||
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
assertCustomisationToggleState(disabled: false, active: true);
|
assertCustomisationToggleState(disabled: false, active: true);
|
||||||
|
|
||||||
AddStep("move mouse to settings area", () => InputManager.MoveMouseTo(this.ChildrenOfType<ModSettingsArea>().Single()));
|
AddStep("move mouse to settings area", () => InputManager.MoveMouseTo(this.ChildrenOfType<ModSettingsArea>().Single()));
|
||||||
@ -224,11 +262,11 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSettingsNotCrossPolluting()
|
public void TestSettingsNotCrossPolluting()
|
||||||
{
|
{
|
||||||
Bindable<IReadOnlyList<Mod>> selectedMods2 = null;
|
Bindable<IReadOnlyList<Mod>> selectedMods2 = null!;
|
||||||
ModSelectOverlay modSelectOverlay2 = null;
|
ModSelectOverlay modSelectOverlay2 = null!;
|
||||||
|
|
||||||
createScreen();
|
createScreen();
|
||||||
AddStep("select diff adjust", () => SelectedMods.Value = new Mod[] { new OsuModDifficultyAdjust() });
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
|
|
||||||
AddStep("set setting", () => modSelectOverlay.ChildrenOfType<OsuSliderBar<float>>().First().Current.Value = 8);
|
AddStep("set setting", () => modSelectOverlay.ChildrenOfType<OsuSliderBar<float>>().First().Current.Value = 8);
|
||||||
|
|
||||||
@ -353,7 +391,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
public void TestExternallySetModIsReplacedByOverlayInstance()
|
public void TestExternallySetModIsReplacedByOverlayInstance()
|
||||||
{
|
{
|
||||||
Mod external = new OsuModDoubleTime();
|
Mod external = new OsuModDoubleTime();
|
||||||
Mod overlayButtonMod = null;
|
Mod overlayButtonMod = null!;
|
||||||
|
|
||||||
createScreen();
|
createScreen();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
@ -458,14 +496,14 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
createScreen();
|
createScreen();
|
||||||
changeRuleset(0);
|
changeRuleset(0);
|
||||||
|
|
||||||
AddStep("select difficulty adjust", () => SelectedMods.Value = new Mod[] { new OsuModDifficultyAdjust() });
|
AddStep("select difficulty adjust via panel", () => getPanelForMod(typeof(OsuModDifficultyAdjust)).TriggerClick());
|
||||||
assertCustomisationToggleState(disabled: false, active: true);
|
assertCustomisationToggleState(disabled: false, active: true);
|
||||||
AddAssert("back button disabled", () => !this.ChildrenOfType<ShearedButton>().First().Enabled.Value);
|
AddAssert("back button disabled", () => !modSelectOverlay.BackButton.Enabled.Value);
|
||||||
|
|
||||||
AddStep("dismiss customisation area", () => InputManager.Key(Key.Escape));
|
AddStep("dismiss customisation area", () => InputManager.Key(Key.Escape));
|
||||||
AddStep("click back button", () =>
|
AddStep("click back button", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(this.ChildrenOfType<ShearedButton>().First());
|
InputManager.MoveMouseTo(modSelectOverlay.BackButton);
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
AddAssert("mod select hidden", () => modSelectOverlay.State.Value == Visibility.Hidden);
|
AddAssert("mod select hidden", () => modSelectOverlay.State.Value == Visibility.Hidden);
|
||||||
@ -474,7 +512,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestColumnHiding()
|
public void TestColumnHiding()
|
||||||
{
|
{
|
||||||
AddStep("create screen", () => Child = modSelectOverlay = new UserModSelectOverlay
|
AddStep("create screen", () => Child = modSelectOverlay = new TestModSelectOverlay
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
State = { Value = Visibility.Visible },
|
State = { Value = Visibility.Visible },
|
||||||
@ -527,15 +565,21 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
private void assertCustomisationToggleState(bool disabled, bool active)
|
private void assertCustomisationToggleState(bool disabled, bool active)
|
||||||
{
|
{
|
||||||
ShearedToggleButton getToggle() => modSelectOverlay.ChildrenOfType<ShearedToggleButton>().Single();
|
AddAssert($"customisation toggle is {(disabled ? "" : "not ")}disabled", () => modSelectOverlay.CustomisationButton.AsNonNull().Active.Disabled == disabled);
|
||||||
|
AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => modSelectOverlay.CustomisationButton.AsNonNull().Active.Value == active);
|
||||||
AddAssert($"customisation toggle is {(disabled ? "" : "not ")}disabled", () => getToggle().Active.Disabled == disabled);
|
|
||||||
AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => getToggle().Active.Value == active);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModPanel getPanelForMod(Type modType)
|
private ModPanel getPanelForMod(Type modType)
|
||||||
=> modSelectOverlay.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.GetType() == modType);
|
=> modSelectOverlay.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.GetType() == modType);
|
||||||
|
|
||||||
|
private class TestModSelectOverlay : UserModSelectOverlay
|
||||||
|
{
|
||||||
|
protected override bool ShowPresets => true;
|
||||||
|
|
||||||
|
public new ShearedButton BackButton => base.BackButton;
|
||||||
|
public new ShearedToggleButton? CustomisationButton => base.CustomisationButton;
|
||||||
|
}
|
||||||
|
|
||||||
private class TestUnimplementedMod : Mod
|
private class TestUnimplementedMod : Mod
|
||||||
{
|
{
|
||||||
public override string Name => "Unimplemented mod";
|
public override string Name => "Unimplemented mod";
|
||||||
|
@ -66,7 +66,10 @@ namespace osu.Game.Overlays.Mods
|
|||||||
private IModHotkeyHandler hotkeyHandler = null!;
|
private IModHotkeyHandler hotkeyHandler = null!;
|
||||||
|
|
||||||
private Task? latestLoadTask;
|
private Task? latestLoadTask;
|
||||||
internal bool ItemsLoaded => latestLoadTask?.IsCompleted == true;
|
private ICollection<ModPanel>? latestLoadedPanels;
|
||||||
|
internal bool ItemsLoaded => latestLoadTask?.IsCompleted == true && latestLoadedPanels?.All(panel => panel.Parent != null) == true;
|
||||||
|
|
||||||
|
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
|
||||||
|
|
||||||
public ModColumn(ModType modType, bool allowIncompatibleSelection)
|
public ModColumn(ModType modType, bool allowIncompatibleSelection)
|
||||||
{
|
{
|
||||||
@ -130,7 +133,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
cancellationTokenSource?.Cancel();
|
cancellationTokenSource?.Cancel();
|
||||||
|
|
||||||
var panels = availableMods.Select(mod => CreateModPanel(mod).With(panel => panel.Shear = Vector2.Zero));
|
var panels = availableMods.Select(mod => CreateModPanel(mod).With(panel => panel.Shear = Vector2.Zero)).ToArray();
|
||||||
|
latestLoadedPanels = panels;
|
||||||
|
|
||||||
latestLoadTask = LoadComponentsAsync(panels, loaded =>
|
latestLoadTask = LoadComponentsAsync(panels, loaded =>
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,18 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Filtered.BindValueChanged(_ => updateFilterState(), true);
|
Filtered.BindValueChanged(_ => updateFilterState(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Select()
|
||||||
|
{
|
||||||
|
modState.PendingConfiguration = Mod.RequiresConfiguration;
|
||||||
|
Active.Value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Deselect()
|
||||||
|
{
|
||||||
|
modState.PendingConfiguration = false;
|
||||||
|
Active.Value = false;
|
||||||
|
}
|
||||||
|
|
||||||
#region Filtering support
|
#region Filtering support
|
||||||
|
|
||||||
private void updateFilterState()
|
private void updateFilterState()
|
||||||
|
@ -37,8 +37,6 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
Title = preset.Value.Name;
|
Title = preset.Value.Name;
|
||||||
Description = preset.Value.Description;
|
Description = preset.Value.Description;
|
||||||
|
|
||||||
Action = toggleRequestedByUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -54,15 +52,19 @@ namespace osu.Game.Overlays.Mods
|
|||||||
selectedMods.BindValueChanged(_ => selectedModsChanged(), true);
|
selectedMods.BindValueChanged(_ => selectedModsChanged(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleRequestedByUser()
|
protected override void Select()
|
||||||
|
{
|
||||||
|
// if the preset is not active at the point of the user click, then set the mods using the preset directly, discarding any previous selections,
|
||||||
|
// which will also have the side effect of activating the preset (see `updateActiveState()`).
|
||||||
|
selectedMods.Value = Preset.Value.Mods.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Deselect()
|
||||||
{
|
{
|
||||||
// if the preset is not active at the point of the user click, then set the mods using the preset directly, discarding any previous selections.
|
|
||||||
// if the preset is active when the user has clicked it, then it means that the set of active mods is exactly equal to the set of mods in the preset
|
// if the preset is active when the user has clicked it, then it means that the set of active mods is exactly equal to the set of mods in the preset
|
||||||
// (there are no other active mods than what the preset specifies, and the mod settings match exactly).
|
// (there are no other active mods than what the preset specifies, and the mod settings match exactly).
|
||||||
// therefore it's safe to just clear selected mods, since it will have the effect of toggling the preset off.
|
// therefore it's safe to just clear selected mods, since it will have the effect of toggling the preset off.
|
||||||
selectedMods.Value = !Active.Value
|
selectedMods.Value = Array.Empty<Mod>();
|
||||||
? Preset.Value.Mods.ToArray()
|
|
||||||
: Array.Empty<Mod>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectedModsChanged()
|
private void selectedModsChanged()
|
||||||
|
@ -87,7 +87,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
if (AllowCustomisation)
|
if (AllowCustomisation)
|
||||||
{
|
{
|
||||||
yield return customisationButton = new ShearedToggleButton(BUTTON_WIDTH)
|
yield return CustomisationButton = new ShearedToggleButton(BUTTON_WIDTH)
|
||||||
{
|
{
|
||||||
Text = ModSelectOverlayStrings.ModCustomisation,
|
Text = ModSelectOverlayStrings.ModCustomisation,
|
||||||
Active = { BindTarget = customisationVisible }
|
Active = { BindTarget = customisationVisible }
|
||||||
@ -107,11 +107,11 @@ namespace osu.Game.Overlays.Mods
|
|||||||
private ColumnScrollContainer columnScroll = null!;
|
private ColumnScrollContainer columnScroll = null!;
|
||||||
private ColumnFlowContainer columnFlow = null!;
|
private ColumnFlowContainer columnFlow = null!;
|
||||||
private FillFlowContainer<ShearedButton> footerButtonFlow = null!;
|
private FillFlowContainer<ShearedButton> footerButtonFlow = null!;
|
||||||
private ShearedButton backButton = null!;
|
|
||||||
|
|
||||||
private DifficultyMultiplierDisplay? multiplierDisplay;
|
private DifficultyMultiplierDisplay? multiplierDisplay;
|
||||||
|
|
||||||
private ShearedToggleButton? customisationButton;
|
protected ShearedButton BackButton { get; private set; } = null!;
|
||||||
|
protected ShearedToggleButton? CustomisationButton { get; private set; }
|
||||||
|
|
||||||
private Sample? columnAppearSample;
|
private Sample? columnAppearSample;
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Horizontal = 70
|
Horizontal = 70
|
||||||
},
|
},
|
||||||
Spacing = new Vector2(10),
|
Spacing = new Vector2(10),
|
||||||
ChildrenEnumerable = CreateFooterButtons().Prepend(backButton = new ShearedButton(BUTTON_WIDTH)
|
ChildrenEnumerable = CreateFooterButtons().Prepend(BackButton = new ShearedButton(BUTTON_WIDTH)
|
||||||
{
|
{
|
||||||
Text = CommonStrings.Back,
|
Text = CommonStrings.Back,
|
||||||
Action = Hide,
|
Action = Hide,
|
||||||
@ -247,8 +247,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
modSettingChangeTracker?.Dispose();
|
modSettingChangeTracker?.Dispose();
|
||||||
|
|
||||||
updateMultiplier();
|
updateMultiplier();
|
||||||
updateCustomisation(val);
|
|
||||||
updateFromExternalSelection();
|
updateFromExternalSelection();
|
||||||
|
updateCustomisation();
|
||||||
|
|
||||||
if (AllowCustomisation)
|
if (AllowCustomisation)
|
||||||
{
|
{
|
||||||
@ -356,25 +356,26 @@ namespace osu.Game.Overlays.Mods
|
|||||||
multiplierDisplay.Current.Value = multiplier;
|
multiplierDisplay.Current.Value = multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCustomisation(ValueChangedEvent<IReadOnlyList<Mod>> valueChangedEvent)
|
private void updateCustomisation()
|
||||||
{
|
{
|
||||||
if (customisationButton == null)
|
if (CustomisationButton == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool anyCustomisableMod = false;
|
bool anyCustomisableModActive = false;
|
||||||
bool anyModWithRequiredCustomisationAdded = false;
|
bool anyModPendingConfiguration = false;
|
||||||
|
|
||||||
foreach (var mod in SelectedMods.Value)
|
foreach (var modState in allAvailableMods)
|
||||||
{
|
{
|
||||||
anyCustomisableMod |= mod.GetSettingsSourceProperties().Any();
|
anyCustomisableModActive |= modState.Active.Value && modState.Mod.GetSettingsSourceProperties().Any();
|
||||||
anyModWithRequiredCustomisationAdded |= valueChangedEvent.OldValue.All(m => m.GetType() != mod.GetType()) && mod.RequiresConfiguration;
|
anyModPendingConfiguration |= modState.PendingConfiguration;
|
||||||
|
modState.PendingConfiguration = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyCustomisableMod)
|
if (anyCustomisableModActive)
|
||||||
{
|
{
|
||||||
customisationVisible.Disabled = false;
|
customisationVisible.Disabled = false;
|
||||||
|
|
||||||
if (anyModWithRequiredCustomisationAdded && !customisationVisible.Value)
|
if (anyModPendingConfiguration && !customisationVisible.Value)
|
||||||
customisationVisible.Value = true;
|
customisationVisible.Value = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -394,7 +395,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
foreach (var button in footerButtonFlow)
|
foreach (var button in footerButtonFlow)
|
||||||
{
|
{
|
||||||
if (button != customisationButton)
|
if (button != CustomisationButton)
|
||||||
button.Enabled.Value = !customisationVisible.Value;
|
button.Enabled.Value = !customisationVisible.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,14 +588,14 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
if (customisationVisible.Value)
|
if (customisationVisible.Value)
|
||||||
{
|
{
|
||||||
Debug.Assert(customisationButton != null);
|
Debug.Assert(CustomisationButton != null);
|
||||||
customisationButton.TriggerClick();
|
CustomisationButton.TriggerClick();
|
||||||
|
|
||||||
if (!immediate)
|
if (!immediate)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
backButton.TriggerClick();
|
BackButton.TriggerClick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,7 +709,18 @@ namespace osu.Game.Overlays.Mods
|
|||||||
FinishTransforms();
|
FinishTransforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate || (Column as ModColumn)?.SelectionAnimationRunning == true;
|
protected override bool RequiresChildrenUpdate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
bool result = base.RequiresChildrenUpdate;
|
||||||
|
|
||||||
|
if (Column is ModColumn modColumn)
|
||||||
|
result |= !modColumn.ItemsLoaded || modColumn.SelectionAnimationRunning;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
|
@ -143,9 +143,25 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Action = () => Active.Toggle();
|
Action = () =>
|
||||||
|
{
|
||||||
|
if (!Active.Value)
|
||||||
|
Select();
|
||||||
|
else
|
||||||
|
Deselect();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs all actions necessary to select this <see cref="ModSelectPanel"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Select();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs all actions necessary to deselect this <see cref="ModSelectPanel"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Deselect();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, ISamplePlaybackDisabler? samplePlaybackDisabler)
|
private void load(AudioManager audio, ISamplePlaybackDisabler? samplePlaybackDisabler)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,13 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public BindableBool Active { get; } = new BindableBool();
|
public BindableBool Active { get; } = new BindableBool();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the mod requires further customisation.
|
||||||
|
/// This flag is read by the <see cref="ModSelectOverlay"/> to determine if the customisation panel should be opened after a mod change
|
||||||
|
/// and cleared after reading.
|
||||||
|
/// </summary>
|
||||||
|
public bool PendingConfiguration { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the mod is currently filtered out due to not matching imposed criteria.
|
/// Whether the mod is currently filtered out due to not matching imposed criteria.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -928,7 +928,7 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SoloModSelectOverlay : UserModSelectOverlay
|
internal class SoloModSelectOverlay : UserModSelectOverlay
|
||||||
{
|
{
|
||||||
protected override bool ShowPresets => true;
|
protected override bool ShowPresets => true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user