1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-23 16:07:24 +08:00

Merge pull request #18264 from peppy/deselect-all-mods-key

Add key binding to deselect all mods
This commit is contained in:
Bartłomiej Dach 2022-05-14 20:48:42 +02:00 committed by GitHub
commit 351f5a30d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 30 deletions

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
@ -55,6 +56,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("customisation area not expanded", () => this.ChildrenOfType<ModSettingsArea>().Single().Height == 0);
}
[Test]
public void TestSelectDeselectAllViaKeyboard()
{
createFreeModSelect();
AddStep("press ctrl+a", () => InputManager.Keys(PlatformAction.SelectAll));
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
AddStep("press backspace", () => InputManager.Key(Key.BackSpace));
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
}
[Test]
public void TestSelectDeselectAll()
{

View File

@ -1,4 +1,4 @@
// 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.
using System;
@ -416,6 +416,19 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("unimplemented mod panel is filtered", () => getPanelForMod(typeof(TestUnimplementedMod)).Filtered.Value);
}
[Test]
public void TestDeselectAllViaKey()
{
createScreen();
changeRuleset(0);
AddStep("select DT + HD", () => SelectedMods.Value = new Mod[] { new OsuModDoubleTime(), new OsuModHidden() });
AddAssert("DT + HD selected", () => modSelectOverlay.ChildrenOfType<ModPanel>().Count(panel => panel.Active.Value) == 2);
AddStep("press backspace", () => InputManager.Key(Key.BackSpace));
AddUntilStep("all mods deselected", () => !SelectedMods.Value.Any());
}
[Test]
public void TestDeselectAllViaButton()
{

View File

@ -109,6 +109,7 @@ namespace osu.Game.Input.Bindings
new KeyBinding(InputKey.F2, GlobalAction.SelectNextRandom),
new KeyBinding(new[] { InputKey.Shift, InputKey.F2 }, GlobalAction.SelectPreviousRandom),
new KeyBinding(InputKey.F3, GlobalAction.ToggleBeatmapOptions),
new KeyBinding(InputKey.BackSpace, GlobalAction.DeselectAllMods),
};
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
@ -318,5 +319,8 @@ namespace osu.Game.Input.Bindings
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.SelectNextGroup))]
SelectNextGroup,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.DeselectAllMods))]
DeselectAllMods,
}
}

View File

@ -207,7 +207,12 @@ namespace osu.Game.Localisation
/// <summary>
/// "Toggle Mod Select"
/// </summary>
public static LocalisableString ToggleModSelection => new TranslatableString(getKey(@"toggle_mod_selection"), @"Toggle Mod Select");
public static LocalisableString ToggleModSelection => new TranslatableString(getKey(@"toggle_mod_selection"), @"Toggle mod select");
/// <summary>
/// "Deselect all mods"
/// </summary>
public static LocalisableString DeselectAllMods => new TranslatableString(getKey(@"deselect_all_mods"), @"Deselect all mods");
/// <summary>
/// "Random"

View File

@ -56,11 +56,32 @@ namespace osu.Game.Overlays.Mods
/// </summary>
protected virtual bool ShowTotalMultiplier => true;
/// <summary>
/// Whether per-mod customisation controls are visible.
/// </summary>
protected virtual bool AllowCustomisation => true;
protected virtual ModColumn CreateModColumn(ModType modType, Key[]? toggleKeys = null) => new ModColumn(modType, false, toggleKeys);
protected virtual IReadOnlyList<Mod> ComputeNewModsFromSelection(IReadOnlyList<Mod> oldSelection, IReadOnlyList<Mod> newSelection) => newSelection;
protected virtual IEnumerable<ShearedButton> CreateFooterButtons() => createDefaultFooterButtons();
protected virtual IEnumerable<ShearedButton> CreateFooterButtons()
{
if (AllowCustomisation)
{
yield return customisationButton = new ShearedToggleButton(BUTTON_WIDTH)
{
Text = ModSelectOverlayStrings.ModCustomisation,
Active = { BindTarget = customisationVisible }
};
}
yield return deselectAllButton = new ShearedButton(BUTTON_WIDTH)
{
Text = CommonStrings.DeselectAll,
Action = DeselectAll
};
}
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
private readonly Dictionary<ModType, IReadOnlyList<ModState>> localAvailableMods = new Dictionary<ModType, IReadOnlyList<ModState>>();
@ -77,6 +98,7 @@ namespace osu.Game.Overlays.Mods
private DifficultyMultiplierDisplay? multiplierDisplay;
private ShearedToggleButton? customisationButton;
private ShearedButton? deselectAllButton;
protected ModSelectOverlay(OverlayColourScheme colourScheme = OverlayColourScheme.Green)
: base(colourScheme)
@ -201,7 +223,7 @@ namespace osu.Game.Overlays.Mods
// This is an optimisation to prevent refreshing the available settings controls when it can be
// reasonably assumed that the settings panel is never to be displayed (e.g. FreeModSelectOverlay).
if (customisationButton != null)
if (AllowCustomisation)
((IBindable<IReadOnlyList<Mod>>)modSettingsArea.SelectedMods).BindTo(SelectedMods);
SelectedMods.BindValueChanged(val =>
@ -256,21 +278,6 @@ namespace osu.Game.Overlays.Mods
};
}
private ShearedButton[] createDefaultFooterButtons()
=> new[]
{
customisationButton = new ShearedToggleButton(BUTTON_WIDTH)
{
Text = ModSelectOverlayStrings.ModCustomisation,
Active = { BindTarget = customisationVisible }
},
new ShearedButton(BUTTON_WIDTH)
{
Text = CommonStrings.DeselectAll,
Action = DeselectAll
}
};
private void createLocalMods()
{
localAvailableMods.Clear();
@ -508,6 +515,10 @@ namespace osu.Game.Overlays.Mods
hideOverlay(true);
return true;
}
case GlobalAction.DeselectAllMods:
deselectAllButton?.TriggerClick();
return true;
}
return base.OnPressed(e);

View File

@ -4,7 +4,11 @@
using System;
using osu.Game.Overlays;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
@ -13,16 +17,20 @@ using osu.Game.Localisation;
namespace osu.Game.Screens.OnlinePlay
{
public class FreeModSelectOverlay : ModSelectOverlay
public class FreeModSelectOverlay : ModSelectOverlay, IKeyBindingHandler<PlatformAction>
{
protected override bool ShowTotalMultiplier => false;
protected override bool AllowCustomisation => false;
public new Func<Mod, bool> IsValidMod
{
get => base.IsValidMod;
set => base.IsValidMod = m => m.UserPlayable && value.Invoke(m);
}
private ShearedButton selectAllButton;
public FreeModSelectOverlay()
: base(OverlayColourScheme.Plum)
{
@ -31,22 +39,32 @@ namespace osu.Game.Screens.OnlinePlay
protected override ModColumn CreateModColumn(ModType modType, Key[] toggleKeys = null) => new ModColumn(modType, true, toggleKeys);
protected override IEnumerable<ShearedButton> CreateFooterButtons() => new[]
{
new ShearedButton(BUTTON_WIDTH)
protected override IEnumerable<ShearedButton> CreateFooterButtons() => base.CreateFooterButtons().Prepend(
selectAllButton = new ShearedButton(BUTTON_WIDTH)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Text = CommonStrings.SelectAll,
Action = SelectAll
},
new ShearedButton(BUTTON_WIDTH)
});
public bool OnPressed(KeyBindingPressEvent<PlatformAction> e)
{
if (e.Repeat)
return false;
switch (e.Action)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Text = CommonStrings.DeselectAll,
Action = DeselectAll
case PlatformAction.SelectAll:
selectAllButton.TriggerClick();
return true;
}
};
return false;
}
public void OnReleased(KeyBindingReleaseEvent<PlatformAction> e)
{
}
}
}