mirror of
https://github.com/ppy/osu.git
synced 2025-03-15 15:27:20 +08:00
Merge pull request #9194 from boswelja/rebind-song-select
Allow rebinding Song Select mods/random/options keys
This commit is contained in:
commit
6eb809f4c4
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
get
|
||||
{
|
||||
if (content == null)
|
||||
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
|
||||
base.Content.Add(content = new OsuInputManager(new OsuRuleset().RulesetInfo));
|
||||
|
||||
return content;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
SetContents(() => new TaikoInputManager(new RulesetInfo { ID = 1 })
|
||||
SetContents(() => new TaikoInputManager(new TaikoRuleset().RulesetInfo)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new Container
|
||||
|
@ -0,0 +1,35 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Select;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
public class TestSceneSongSelectFooter : OsuManualInputManagerTestScene
|
||||
{
|
||||
public TestSceneSongSelectFooter()
|
||||
{
|
||||
AddStep("Create footer", () =>
|
||||
{
|
||||
Footer footer;
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
footer = new Footer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
footer.AddButton(new FooterButtonMods(), null);
|
||||
footer.AddButton(new FooterButtonRandom
|
||||
{
|
||||
NextRandom = () => { },
|
||||
PreviousRandom = () => { },
|
||||
}, null);
|
||||
footer.AddButton(new FooterButtonOptions(), null);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -64,12 +64,20 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
protected override void ReloadMappings()
|
||||
{
|
||||
var defaults = DefaultKeyBindings.ToList();
|
||||
|
||||
if (ruleset != null && !ruleset.ID.HasValue)
|
||||
// if the provided ruleset is not stored to the database, we have no way to retrieve custom bindings.
|
||||
// fallback to defaults instead.
|
||||
KeyBindings = DefaultKeyBindings;
|
||||
KeyBindings = defaults;
|
||||
else
|
||||
KeyBindings = store.Query(ruleset?.ID, variant).ToList();
|
||||
{
|
||||
KeyBindings = store.Query(ruleset?.ID, variant)
|
||||
// this ordering is important to ensure that we read entries from the database in the order
|
||||
// enforced by DefaultKeyBindings. allow for song select to handle actions that may otherwise
|
||||
// have been eaten by the music controller due to query order.
|
||||
.OrderBy(b => defaults.FindIndex(d => (int)d.Action == b.IntAction)).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,11 @@ namespace osu.Game.Input.Bindings
|
||||
handler = game;
|
||||
}
|
||||
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings);
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
|
||||
.Concat(EditorKeyBindings)
|
||||
.Concat(InGameKeyBindings)
|
||||
.Concat(SongSelectKeyBindings)
|
||||
.Concat(AudioControlKeyBindings);
|
||||
|
||||
public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
|
||||
{
|
||||
@ -80,6 +84,14 @@ namespace osu.Game.Input.Bindings
|
||||
new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD),
|
||||
};
|
||||
|
||||
public IEnumerable<KeyBinding> SongSelectKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.F1, GlobalAction.ToggleModSelection),
|
||||
new KeyBinding(InputKey.F2, GlobalAction.SelectNextRandom),
|
||||
new KeyBinding(new[] { InputKey.Shift, InputKey.F2 }, GlobalAction.SelectPreviousRandom),
|
||||
new KeyBinding(InputKey.F3, GlobalAction.ToggleBeatmapOptions)
|
||||
};
|
||||
|
||||
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Up }, GlobalAction.IncreaseVolume),
|
||||
@ -217,5 +229,18 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
[Description("Toggle in-game interface")]
|
||||
ToggleInGameInterface,
|
||||
|
||||
// Song select keybindings
|
||||
[Description("Toggle Mod Select")]
|
||||
ToggleModSelection,
|
||||
|
||||
[Description("Random")]
|
||||
SelectNextRandom,
|
||||
|
||||
[Description("Rewind")]
|
||||
SelectPreviousRandom,
|
||||
|
||||
[Description("Beatmap Options")]
|
||||
ToggleBeatmapOptions,
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
{
|
||||
Add(new DefaultBindingsSubsection(manager));
|
||||
Add(new AudioControlKeyBindingsSubsection(manager));
|
||||
Add(new SongSelectKeyBindingSubsection(manager));
|
||||
Add(new InGameKeyBindingsSubsection(manager));
|
||||
Add(new EditorKeyBindingsSubsection(manager));
|
||||
}
|
||||
@ -36,6 +37,17 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
}
|
||||
}
|
||||
|
||||
private class SongSelectKeyBindingSubsection : KeyBindingsSubsection
|
||||
{
|
||||
protected override string Header => "Song Select";
|
||||
|
||||
public SongSelectKeyBindingSubsection(GlobalActionContainer manager)
|
||||
: base(null)
|
||||
{
|
||||
Defaults = manager.SongSelectKeyBindings;
|
||||
}
|
||||
}
|
||||
|
||||
private class InGameKeyBindingsSubsection : KeyBindingsSubsection
|
||||
{
|
||||
protected override string Header => "In Game";
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -13,10 +12,12 @@ using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Framework.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class FooterButton : OsuClickableContainer
|
||||
public class FooterButton : OsuClickableContainer, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
public const float SHEAR_WIDTH = 7.5f;
|
||||
|
||||
@ -105,6 +106,7 @@ namespace osu.Game.Screens.Select
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Child = SpriteText = new OsuSpriteText
|
||||
{
|
||||
AlwaysPresent = true,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
@ -118,7 +120,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
public Action Hovered;
|
||||
public Action HoverLost;
|
||||
public Key? Hotkey;
|
||||
public GlobalAction? Hotkey;
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
@ -168,15 +170,17 @@ namespace osu.Game.Screens.Select
|
||||
return base.OnClick(e);
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
public virtual bool OnPressed(GlobalAction action)
|
||||
{
|
||||
if (!e.Repeat && e.Key == Hotkey)
|
||||
if (action == Hotkey)
|
||||
{
|
||||
Click();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void OnReleased(GlobalAction action) { }
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
using osu.Game.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
@ -57,7 +57,7 @@ namespace osu.Game.Screens.Select
|
||||
lowMultiplierColour = colours.Red;
|
||||
highMultiplierColour = colours.Green;
|
||||
Text = @"mods";
|
||||
Hotkey = Key.F1;
|
||||
Hotkey = GlobalAction.ToggleModSelection;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -4,7 +4,7 @@
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Input;
|
||||
using osu.Game.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
@ -16,7 +16,7 @@ namespace osu.Game.Screens.Select
|
||||
SelectedColour = colours.Blue;
|
||||
DeselectedColour = SelectedColour.Opacity(0.5f);
|
||||
Text = @"options";
|
||||
Hotkey = Key.F3;
|
||||
Hotkey = GlobalAction.ToggleBeatmapOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,23 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK.Input;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class FooterButtonRandom : FooterButton
|
||||
{
|
||||
private readonly SpriteText secondaryText;
|
||||
private bool secondaryActive;
|
||||
public Action NextRandom { get; set; }
|
||||
public Action PreviousRandom { get; set; }
|
||||
|
||||
public FooterButtonRandom()
|
||||
{
|
||||
TextContainer.Add(secondaryText = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = @"rewind",
|
||||
Alpha = 0,
|
||||
});
|
||||
|
||||
// force both text sprites to always be present to avoid width flickering while they're being swapped out
|
||||
SpriteText.AlwaysPresent = secondaryText.AlwaysPresent = true;
|
||||
}
|
||||
private bool rewindSearch;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
@ -37,34 +25,57 @@ namespace osu.Game.Screens.Select
|
||||
SelectedColour = colours.Green;
|
||||
DeselectedColour = SelectedColour.Opacity(0.5f);
|
||||
Text = @"random";
|
||||
Hotkey = Key.F2;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
secondaryActive = e.ShiftPressed;
|
||||
updateText();
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyUpEvent e)
|
||||
{
|
||||
secondaryActive = e.ShiftPressed;
|
||||
updateText();
|
||||
base.OnKeyUp(e);
|
||||
}
|
||||
|
||||
private void updateText()
|
||||
{
|
||||
if (secondaryActive)
|
||||
Action = () =>
|
||||
{
|
||||
SpriteText.FadeOut(120, Easing.InQuad);
|
||||
secondaryText.FadeIn(120, Easing.InQuad);
|
||||
if (rewindSearch)
|
||||
{
|
||||
const double fade_time = 500;
|
||||
|
||||
OsuSpriteText rewindSpriteText;
|
||||
|
||||
TextContainer.Add(rewindSpriteText = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
Text = @"rewind",
|
||||
AlwaysPresent = true, // make sure the button is sized large enough to always show this
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
});
|
||||
|
||||
rewindSpriteText.FadeOutFromOne(fade_time, Easing.In);
|
||||
rewindSpriteText.MoveTo(Vector2.Zero).MoveTo(new Vector2(0, 10), fade_time, Easing.In);
|
||||
rewindSpriteText.Expire();
|
||||
|
||||
SpriteText.FadeInFromZero(fade_time, Easing.In);
|
||||
|
||||
PreviousRandom.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
NextRandom.Invoke();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override bool OnPressed(GlobalAction action)
|
||||
{
|
||||
rewindSearch = action == GlobalAction.SelectPreviousRandom;
|
||||
|
||||
if (action != GlobalAction.SelectNextRandom && action != GlobalAction.SelectPreviousRandom)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
Click();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnReleased(GlobalAction action)
|
||||
{
|
||||
if (action == GlobalAction.SelectPreviousRandom)
|
||||
{
|
||||
SpriteText.FadeIn(120, Easing.InQuad);
|
||||
secondaryText.FadeOut(120, Easing.InQuad);
|
||||
rewindSearch = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +307,11 @@ namespace osu.Game.Screens.Select
|
||||
protected virtual IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons() => new (FooterButton, OverlayContainer)[]
|
||||
{
|
||||
(new FooterButtonMods { Current = Mods }, ModSelect),
|
||||
(new FooterButtonRandom { Action = triggerRandom }, null),
|
||||
(new FooterButtonRandom
|
||||
{
|
||||
NextRandom = () => Carousel.SelectNextRandom(),
|
||||
PreviousRandom = Carousel.SelectPreviousRandom
|
||||
}, null),
|
||||
(new FooterButtonOptions(), BeatmapOptions)
|
||||
};
|
||||
|
||||
@ -522,14 +526,6 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerRandom()
|
||||
{
|
||||
if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed)
|
||||
Carousel.SelectPreviousRandom();
|
||||
else
|
||||
Carousel.SelectNextRandom();
|
||||
}
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
Loading…
x
Reference in New Issue
Block a user