mirror of
https://github.com/ppy/osu.git
synced 2024-11-12 07:27:51 +08:00
Merge pull request #18264 from peppy/deselect-all-mods-key
Add key binding to deselect all mods
This commit is contained in:
commit
351f5a30d0
@ -7,6 +7,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Mods;
|
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);
|
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]
|
[Test]
|
||||||
public void TestSelectDeselectAll()
|
public void TestSelectDeselectAll()
|
||||||
{
|
{
|
||||||
|
@ -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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -416,6 +416,19 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("unimplemented mod panel is filtered", () => getPanelForMod(typeof(TestUnimplementedMod)).Filtered.Value);
|
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]
|
[Test]
|
||||||
public void TestDeselectAllViaButton()
|
public void TestDeselectAllViaButton()
|
||||||
{
|
{
|
||||||
|
@ -109,6 +109,7 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(InputKey.F2, GlobalAction.SelectNextRandom),
|
new KeyBinding(InputKey.F2, GlobalAction.SelectNextRandom),
|
||||||
new KeyBinding(new[] { InputKey.Shift, InputKey.F2 }, GlobalAction.SelectPreviousRandom),
|
new KeyBinding(new[] { InputKey.Shift, InputKey.F2 }, GlobalAction.SelectPreviousRandom),
|
||||||
new KeyBinding(InputKey.F3, GlobalAction.ToggleBeatmapOptions),
|
new KeyBinding(InputKey.F3, GlobalAction.ToggleBeatmapOptions),
|
||||||
|
new KeyBinding(InputKey.BackSpace, GlobalAction.DeselectAllMods),
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
|
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
|
||||||
@ -318,5 +319,8 @@ namespace osu.Game.Input.Bindings
|
|||||||
|
|
||||||
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.SelectNextGroup))]
|
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.SelectNextGroup))]
|
||||||
SelectNextGroup,
|
SelectNextGroup,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.DeselectAllMods))]
|
||||||
|
DeselectAllMods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,12 @@ namespace osu.Game.Localisation
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Toggle Mod Select"
|
/// "Toggle Mod Select"
|
||||||
/// </summary>
|
/// </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>
|
/// <summary>
|
||||||
/// "Random"
|
/// "Random"
|
||||||
|
@ -56,11 +56,32 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual bool ShowTotalMultiplier => true;
|
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 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 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 Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||||
private readonly Dictionary<ModType, IReadOnlyList<ModState>> localAvailableMods = new Dictionary<ModType, IReadOnlyList<ModState>>();
|
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 DifficultyMultiplierDisplay? multiplierDisplay;
|
||||||
|
|
||||||
private ShearedToggleButton? customisationButton;
|
private ShearedToggleButton? customisationButton;
|
||||||
|
private ShearedButton? deselectAllButton;
|
||||||
|
|
||||||
protected ModSelectOverlay(OverlayColourScheme colourScheme = OverlayColourScheme.Green)
|
protected ModSelectOverlay(OverlayColourScheme colourScheme = OverlayColourScheme.Green)
|
||||||
: base(colourScheme)
|
: 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
|
// 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).
|
// 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);
|
((IBindable<IReadOnlyList<Mod>>)modSettingsArea.SelectedMods).BindTo(SelectedMods);
|
||||||
|
|
||||||
SelectedMods.BindValueChanged(val =>
|
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()
|
private void createLocalMods()
|
||||||
{
|
{
|
||||||
localAvailableMods.Clear();
|
localAvailableMods.Clear();
|
||||||
@ -508,6 +515,10 @@ namespace osu.Game.Overlays.Mods
|
|||||||
hideOverlay(true);
|
hideOverlay(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GlobalAction.DeselectAllMods:
|
||||||
|
deselectAllButton?.TriggerClick();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.OnPressed(e);
|
return base.OnPressed(e);
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
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.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -13,16 +17,20 @@ using osu.Game.Localisation;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay
|
namespace osu.Game.Screens.OnlinePlay
|
||||||
{
|
{
|
||||||
public class FreeModSelectOverlay : ModSelectOverlay
|
public class FreeModSelectOverlay : ModSelectOverlay, IKeyBindingHandler<PlatformAction>
|
||||||
{
|
{
|
||||||
protected override bool ShowTotalMultiplier => false;
|
protected override bool ShowTotalMultiplier => false;
|
||||||
|
|
||||||
|
protected override bool AllowCustomisation => false;
|
||||||
|
|
||||||
public new Func<Mod, bool> IsValidMod
|
public new Func<Mod, bool> IsValidMod
|
||||||
{
|
{
|
||||||
get => base.IsValidMod;
|
get => base.IsValidMod;
|
||||||
set => base.IsValidMod = m => m.UserPlayable && value.Invoke(m);
|
set => base.IsValidMod = m => m.UserPlayable && value.Invoke(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ShearedButton selectAllButton;
|
||||||
|
|
||||||
public FreeModSelectOverlay()
|
public FreeModSelectOverlay()
|
||||||
: base(OverlayColourScheme.Plum)
|
: 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 ModColumn CreateModColumn(ModType modType, Key[] toggleKeys = null) => new ModColumn(modType, true, toggleKeys);
|
||||||
|
|
||||||
protected override IEnumerable<ShearedButton> CreateFooterButtons() => new[]
|
protected override IEnumerable<ShearedButton> CreateFooterButtons() => base.CreateFooterButtons().Prepend(
|
||||||
{
|
selectAllButton = new ShearedButton(BUTTON_WIDTH)
|
||||||
new ShearedButton(BUTTON_WIDTH)
|
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Text = CommonStrings.SelectAll,
|
Text = CommonStrings.SelectAll,
|
||||||
Action = SelectAll
|
Action = SelectAll
|
||||||
},
|
});
|
||||||
new ShearedButton(BUTTON_WIDTH)
|
|
||||||
|
public bool OnPressed(KeyBindingPressEvent<PlatformAction> e)
|
||||||
|
{
|
||||||
|
if (e.Repeat)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
case PlatformAction.SelectAll:
|
||||||
Origin = Anchor.BottomLeft,
|
selectAllButton.TriggerClick();
|
||||||
Text = CommonStrings.DeselectAll,
|
return true;
|
||||||
Action = DeselectAll
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnReleased(KeyBindingReleaseEvent<PlatformAction> e)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user