diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index fceee90d06..dbc354ae07 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -18,6 +18,8 @@ namespace osu.Game.Graphics.Containers private readonly Container content = new Container { RelativeSizeAxes = Axes.Both }; + private HoverSounds samples = null!; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => // base call is checked for cases when `OsuClickableContainer` has masking applied to it directly (ie. externally in object initialisation). base.ReceivePositionalInputAt(screenSpacePos) @@ -33,6 +35,14 @@ namespace osu.Game.Graphics.Containers this.sampleSet = sampleSet; } + public void TriggerClickWithSound() + { + TriggerClick(); + + // TriggerClick doesn't recursively fire the event so we need to manually do this. + (samples as HoverClickSounds)?.PlayClickSample(); + } + public virtual LocalisableString TooltipText { get; set; } [BackgroundDependencyLoader] @@ -46,7 +56,7 @@ namespace osu.Game.Graphics.Containers AddRangeInternal(new Drawable[] { - CreateHoverSounds(sampleSet), + samples = CreateHoverSounds(sampleSet), content, }); } diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 884834ebe8..fea33bfa9d 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -42,18 +42,20 @@ namespace osu.Game.Graphics.UserInterface this.buttons = buttons ?? new[] { MouseButton.Left }; } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleClick = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select") + ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); + + sampleClickDisabled = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select-disabled") + ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select-disabled"); + } + protected override bool OnClick(ClickEvent e) { if (buttons.Contains(e.Button)) - { - var channel = Enabled.Value ? sampleClick?.GetChannel() : sampleClickDisabled?.GetChannel(); - - if (channel != null) - { - channel.Frequency.Value = 0.99 + RNG.NextDouble(0.02); - channel.Play(); - } - } + PlayClickSample(); return base.OnClick(e); } @@ -66,14 +68,15 @@ namespace osu.Game.Graphics.UserInterface base.PlayHoverSample(); } - [BackgroundDependencyLoader] - private void load(AudioManager audio) + public void PlayClickSample() { - sampleClick = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select") - ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); + var channel = Enabled.Value ? sampleClick?.GetChannel() : sampleClickDisabled?.GetChannel(); - sampleClickDisabled = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select-disabled") - ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select-disabled"); + if (channel != null) + { + channel.Frequency.Value = 0.99 + RNG.NextDouble(0.02); + channel.Play(); + } } } } diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/PoolSelector.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/PoolSelector.cs index eb84a525a8..71f976329f 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/PoolSelector.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/PoolSelector.cs @@ -1,6 +1,7 @@ // 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; @@ -15,6 +16,7 @@ using osu.Game.Overlays; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; +using osuTK.Input; namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue { @@ -64,8 +66,34 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue }, true); } + protected override bool OnKeyDown(KeyDownEvent e) + { + var currentSelection = poolFlow.SingleOrDefault(b => b.IsSelected); + + switch (e.Key) + { + case Key.Left: + { + var next = poolFlow.Reverse().SkipWhile(b => b != currentSelection).Skip(1).FirstOrDefault(); + (next ?? poolFlow.Last()).TriggerClickWithSound(); + return true; + } + + case Key.Right: + { + var next = poolFlow.SkipWhile(b => b != currentSelection).Skip(1).FirstOrDefault(); + (next ?? poolFlow.First()).TriggerClickWithSound(); + return true; + } + } + + return false; + } + private partial class SelectorButton : OsuAnimatedButton { + public bool IsSelected => SelectedPool.Value?.Equals(pool) == true; + public readonly Bindable SelectedPool = new Bindable(); [Resolved] @@ -77,6 +105,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue private Box flashLayer = null!; public SelectorButton(MatchmakingPool pool) + : base(HoverSampleSet.ButtonSidebar) { this.pool = pool; @@ -129,23 +158,21 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue protected override bool OnHover(HoverEvent e) { - if (!isSelected) + if (!IsSelected) flashLayer.FadeTo(0.05f, 200, Easing.OutQuint); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - if (!isSelected) + if (!IsSelected) flashLayer.FadeTo(0f, 200, Easing.OutQuint); base.OnHoverLost(e); } - private bool isSelected => SelectedPool.Value?.Equals(pool) == true; - private void onSelectionChanged(ValueChangedEvent selection) { - if (isSelected) + if (IsSelected) { this.ScaleTo(1.2f, 200, Easing.OutQuint); iconSprite.FadeColour(Color4.Gold, 100, Easing.OutQuint); diff --git a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/ScreenQueue.cs b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/ScreenQueue.cs index d13bc9c2da..501a46d4c4 100644 --- a/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/ScreenQueue.cs +++ b/osu.Game/Screens/OnlinePlay/Matchmaking/Queue/ScreenQueue.cs @@ -15,11 +15,14 @@ using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Framework.Screens; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Input.Bindings; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Matchmaking; @@ -350,7 +353,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue Text = "Found a match!", Font = OsuFont.GetFont(size: 32, weight: FontWeight.Regular, typeface: Typeface.TorusAlternate), }, - new ShearedButton(200) + new SelectionButton(200) { DarkerColour = colours.YellowDark, LighterColour = colours.YellowLight, @@ -440,7 +443,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue InRoom } - private partial class BeginQueueingButton : ShearedButton + private partial class BeginQueueingButton : SelectionButton { public readonly IBindable SelectedPool = new Bindable(); @@ -456,5 +459,28 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue SelectedPool.BindValueChanged(p => Enabled.Value = p.NewValue != null, true); } } + + private partial class SelectionButton : ShearedButton, IKeyBindingHandler + { + public SelectionButton(float? width = null, float height = DEFAULT_HEIGHT) + : base(width, height) + { + } + + public bool OnPressed(KeyBindingPressEvent e) + { + if (e.Action == GlobalAction.Select && !e.Repeat) + { + TriggerClickWithSound(); + return true; + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } } }