From df51d345c5e1e49b98c43b898f38ccd0403b5abf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2025 17:36:47 +0900 Subject: [PATCH 1/3] Change menus to fade out with a slight delay so settings changes are visible Useful for cases like https://github.com/ppy/osu/pull/31778, where a change to one setting can affect another. --- osu.Game/Graphics/UserInterface/OsuMenu.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 7cc1bab25f6d..9b099c088405 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -68,7 +68,9 @@ protected override void AnimateClose() if (!TopLevelMenu && wasOpened) menuSamples?.PlayCloseSample(); - this.FadeOut(300, Easing.OutQuint); + this.Delay(50) + .FadeOut(300, Easing.OutQuint); + wasOpened = false; } @@ -77,12 +79,21 @@ protected override void UpdateSize(Vector2 newSize) if (Direction == Direction.Vertical) { Width = newSize.X; - this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + + if (newSize.Y > 0) + this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + else + // Delay until the fade out finishes from AnimateClose. + this.Delay(350).ResizeHeightTo(0); } else { Height = newSize.Y; - this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + if (newSize.X > 0) + this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + else + // Delay until the fade out finishes from AnimateClose. + this.Delay(350).ResizeWidthTo(0); } } From 099ce3953127e075f73ee5b11d0f1307e012fe07 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Feb 2025 23:21:41 +0900 Subject: [PATCH 2/3] Use same delay in context menus --- osu.Game/Graphics/UserInterface/OsuContextMenu.cs | 7 +++---- osu.Game/Graphics/UserInterface/OsuMenu.cs | 7 +++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 433d37834f8c..e81d77ce43ca 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -12,8 +12,6 @@ namespace osu.Game.Graphics.UserInterface { public partial class OsuContextMenu : OsuMenu { - private const int fade_duration = 250; - [Resolved] private OsuMenuSamples menuSamples { get; set; } = null!; @@ -48,7 +46,7 @@ private void load(OsuColour colours) protected override void AnimateOpen() { wasOpened = true; - this.FadeIn(fade_duration, Easing.OutQuint); + this.FadeIn(FADE_DURATION, Easing.OutQuint); if (!playClickSample) return; @@ -59,7 +57,8 @@ protected override void AnimateOpen() protected override void AnimateClose() { - this.FadeOut(fade_duration, Easing.OutQuint); + this.Delay(DELAY_BEFORE_FADE_OUT) + .FadeOut(FADE_DURATION, Easing.OutQuint); if (wasOpened) menuSamples.PlayCloseSample(); diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 9b099c088405..a75769b16b13 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -18,6 +18,9 @@ namespace osu.Game.Graphics.UserInterface { public partial class OsuMenu : Menu { + protected const double DELAY_BEFORE_FADE_OUT = 50; + protected const double FADE_DURATION = 280; + // todo: this shouldn't be required after https://github.com/ppy/osu-framework/issues/4519 is fixed. private bool wasOpened; @@ -68,8 +71,8 @@ protected override void AnimateClose() if (!TopLevelMenu && wasOpened) menuSamples?.PlayCloseSample(); - this.Delay(50) - .FadeOut(300, Easing.OutQuint); + this.Delay(DELAY_BEFORE_FADE_OUT) + .FadeOut(FADE_DURATION, Easing.OutQuint); wasOpened = false; } From 2356d3e2d0c02c8e12fb27b8ef1b3b5766d9a5e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2025 16:24:13 +0900 Subject: [PATCH 3/3] Refactor `OsuContextMenu` to avoid code duplication --- .../Graphics/UserInterface/OsuContextMenu.cs | 33 ++++--------------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 26 ++++++++++----- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index e81d77ce43ca..72ffde357493 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -15,12 +15,8 @@ public partial class OsuContextMenu : OsuMenu [Resolved] private OsuMenuSamples menuSamples { get; set; } = null!; - // todo: this shouldn't be required after https://github.com/ppy/osu-framework/issues/4519 is fixed. - private bool wasOpened; - private readonly bool playClickSample; - - public OsuContextMenu(bool playClickSample = false) - : base(Direction.Vertical) + public OsuContextMenu(bool playSamples) + : base(Direction.Vertical, topLevelMenu: false, playSamples) { MaskingContainer.CornerRadius = 5; MaskingContainer.EdgeEffect = new EdgeEffectParameters @@ -33,8 +29,6 @@ public OsuContextMenu(bool playClickSample = false) ItemsContainer.Padding = new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; MaxHeight = 250; - - this.playClickSample = playClickSample; } [BackgroundDependencyLoader] @@ -45,27 +39,12 @@ private void load(OsuColour colours) protected override void AnimateOpen() { - wasOpened = true; - this.FadeIn(FADE_DURATION, Easing.OutQuint); - - if (!playClickSample) - return; - - menuSamples.PlayClickSample(); - menuSamples.PlayOpenSample(); - } - - protected override void AnimateClose() - { - this.Delay(DELAY_BEFORE_FADE_OUT) - .FadeOut(FADE_DURATION, Easing.OutQuint); - - if (wasOpened) - menuSamples.PlayCloseSample(); + if (PlaySamples && !WasOpened) + menuSamples.PlayClickSample(); - wasOpened = false; + base.AnimateOpen(); } - protected override Menu CreateSubMenu() => new OsuContextMenu(); + protected override Menu CreateSubMenu() => new OsuContextMenu(false); // sub menu samples are handled by OsuMenu.OnSubmenuOpen. } } diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index a75769b16b13..11d9000dfa06 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -22,20 +22,28 @@ public partial class OsuMenu : Menu protected const double FADE_DURATION = 280; // todo: this shouldn't be required after https://github.com/ppy/osu-framework/issues/4519 is fixed. - private bool wasOpened; + protected bool WasOpened { get; private set; } + + public bool PlaySamples { get; } [Resolved] private OsuMenuSamples menuSamples { get; set; } = null!; public OsuMenu(Direction direction, bool topLevelMenu = false) + : this(direction, topLevelMenu, playSamples: !topLevelMenu) + { + } + + protected OsuMenu(Direction direction, bool topLevelMenu, bool playSamples) : base(direction, topLevelMenu) { + PlaySamples = playSamples; BackgroundColour = Color4.Black.Opacity(0.5f); MaskingContainer.CornerRadius = 4; ItemsContainer.Padding = new MarginPadding(5); - OnSubmenuOpen += _ => { menuSamples?.PlaySubOpenSample(); }; + OnSubmenuOpen += _ => menuSamples?.PlaySubOpenSample(); } protected override void Update() @@ -59,22 +67,22 @@ protected override void Update() protected override void AnimateOpen() { - if (!TopLevelMenu && !wasOpened) + if (PlaySamples && !WasOpened) menuSamples?.PlayOpenSample(); - this.FadeIn(300, Easing.OutQuint); - wasOpened = true; + WasOpened = true; + this.FadeIn(FADE_DURATION, Easing.OutQuint); } protected override void AnimateClose() { - if (!TopLevelMenu && wasOpened) + if (PlaySamples && WasOpened) menuSamples?.PlayCloseSample(); this.Delay(DELAY_BEFORE_FADE_OUT) .FadeOut(FADE_DURATION, Easing.OutQuint); - wasOpened = false; + WasOpened = false; } protected override void UpdateSize(Vector2 newSize) @@ -87,7 +95,7 @@ protected override void UpdateSize(Vector2 newSize) this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); else // Delay until the fade out finishes from AnimateClose. - this.Delay(350).ResizeHeightTo(0); + this.Delay(DELAY_BEFORE_FADE_OUT + FADE_DURATION).ResizeHeightTo(0); } else { @@ -96,7 +104,7 @@ protected override void UpdateSize(Vector2 newSize) this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); else // Delay until the fade out finishes from AnimateClose. - this.Delay(350).ResizeWidthTo(0); + this.Delay(DELAY_BEFORE_FADE_OUT + FADE_DURATION).ResizeWidthTo(0); } }