diff --git a/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs new file mode 100644 index 0000000000..55f43cfe46 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs @@ -0,0 +1,50 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; +using osu.Game.Configuration; + +namespace osu.Game.Graphics.UserInterface +{ + /// + /// Handles debouncing hover sounds at a global level to ensure the effects are not overwhelming. + /// + public abstract class HoverSampleDebounceComponent : CompositeDrawable + { + /// + /// Length of debounce for hover sound playback, in milliseconds. + /// + public double HoverDebounceTime { get; } = 20; + + private Bindable lastPlaybackTime; + + [BackgroundDependencyLoader] + private void load(AudioManager audio, SessionStatics statics) + { + lastPlaybackTime = statics.GetBindable(Static.LastHoverSoundPlaybackTime); + } + + protected override bool OnHover(HoverEvent e) + { + // hover sounds shouldn't be played during scroll operations. + if (e.HasAnyButtonPressed) + return false; + + bool enoughTimePassedSinceLastPlayback = !lastPlaybackTime.Value.HasValue || Time.Current - lastPlaybackTime.Value >= HoverDebounceTime; + + if (enoughTimePassedSinceLastPlayback) + { + PlayHoverSample(); + lastPlaybackTime.Value = Time.Current; + } + + return false; + } + + public abstract void PlayHoverSample(); + } +} diff --git a/osu.Game/Graphics/UserInterface/HoverSounds.cs b/osu.Game/Graphics/UserInterface/HoverSounds.cs index fa43d4543f..29238377c7 100644 --- a/osu.Game/Graphics/UserInterface/HoverSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverSounds.cs @@ -5,11 +5,8 @@ using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Framework.Utils; @@ -19,19 +16,12 @@ namespace osu.Game.Graphics.UserInterface /// Adds hover sounds to a drawable. /// Does not draw anything. /// - public class HoverSounds : CompositeDrawable + public class HoverSounds : HoverSampleDebounceComponent { private SampleChannel sampleHover; - /// - /// Length of debounce for hover sound playback, in milliseconds. - /// - public double HoverDebounceTime { get; } = 20; - protected readonly HoverSampleSet SampleSet; - private Bindable lastPlaybackTime; - public HoverSounds(HoverSampleSet sampleSet = HoverSampleSet.Normal) { SampleSet = sampleSet; @@ -41,27 +31,13 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(AudioManager audio, SessionStatics statics) { - lastPlaybackTime = statics.GetBindable(Static.LastHoverSoundPlaybackTime); - sampleHover = audio.Samples.Get($@"UI/generic-hover{SampleSet.GetDescription()}"); } - protected override bool OnHover(HoverEvent e) + public override void PlayHoverSample() { - if (sampleHover == null) - return false; - - bool enoughTimePassedSinceLastPlayback = !lastPlaybackTime.Value.HasValue || Time.Current - lastPlaybackTime.Value >= HoverDebounceTime; - - if (enoughTimePassedSinceLastPlayback) - { - sampleHover.Frequency.Value = 0.96 + RNG.NextDouble(0.08); - sampleHover.Play(); - - lastPlaybackTime.Value = Time.Current; - } - - return false; + sampleHover.Frequency.Value = 0.96 + RNG.NextDouble(0.08); + sampleHover.Play(); } } diff --git a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs index 4f53a6e202..90eebfc05b 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Utils; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; @@ -20,10 +21,6 @@ namespace osu.Game.Screens.Select.Carousel { public class CarouselHeader : Container { - private SampleChannel sampleHover; - - private readonly Box hoverLayer; - public Container BorderContainer; public readonly Bindable State = new Bindable(CarouselItemState.NotSelected); @@ -44,23 +41,11 @@ namespace osu.Game.Screens.Select.Carousel Children = new Drawable[] { Content, - hoverLayer = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Blending = BlendingParameters.Additive, - }, + new HoverLayer() } }; } - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colours) - { - sampleHover = audio.Samples.Get("SongSelect/song-ping"); - hoverLayer.Colour = colours.Blue.Opacity(0.1f); - } - protected override void LoadComplete() { base.LoadComplete(); @@ -97,22 +82,50 @@ namespace osu.Game.Screens.Select.Carousel } } - protected override bool OnHover(HoverEvent e) + public class HoverLayer : HoverSampleDebounceComponent { - if (sampleHover != null) + private SampleChannel sampleHover; + + private Box box; + + public HoverLayer() { + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + InternalChild = box = new Box + { + Colour = colours.Blue.Opacity(0.1f), + Alpha = 0, + Blending = BlendingParameters.Additive, + RelativeSizeAxes = Axes.Both, + }; + + sampleHover = audio.Samples.Get("SongSelect/song-ping"); + } + + protected override bool OnHover(HoverEvent e) + { + box.FadeIn(100, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + box.FadeOut(1000, Easing.OutQuint); + base.OnHoverLost(e); + } + + public override void PlayHoverSample() + { + if (sampleHover == null) return; + sampleHover.Frequency.Value = 0.90 + RNG.NextDouble(0.2); sampleHover.Play(); } - - hoverLayer.FadeIn(100, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - hoverLayer.FadeOut(1000, Easing.OutQuint); - base.OnHoverLost(e); } } }