From f7febdac5e20ba71eb1dee4c64dd1916a558135a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 22:48:33 +0100 Subject: [PATCH 1/4] Add failing assertion --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index acb68fc9cd..aef6f9ade0 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -207,7 +207,7 @@ namespace osu.Game.Tests.Visual.Menus AddStep("set toolbar width", () => { toolbar.RelativeSizeAxes = Axes.None; - toolbar.Width = 0; + toolbar.Width = 400; }); AddStep("move mouse over news toggle button", () => { @@ -215,6 +215,7 @@ namespace osu.Game.Tests.Visual.Menus InputManager.MoveMouseTo(button); }); AddAssert("no ruleset toggle buttons hovered", () => !toolbar.ChildrenOfType().Any(button => button.IsHovered)); + AddUntilStep("toolbar gradient visible", () => toolbar.ChildrenOfType().Single().Children.All(d => d.Alpha > 0)); } public partial class TestToolbar : Toolbar From bf975eb48a89707d69b62ff1e2bebd434464ad2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 23:02:45 +0100 Subject: [PATCH 2/4] Fix toolbar gradient not showing when mouse is hovered over buttons --- osu.Game/Overlays/Toolbar/Toolbar.cs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index ac0f822f68..a559363bbf 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -13,6 +13,7 @@ using osuTK; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets; using osu.Framework.Input.Bindings; @@ -196,6 +197,9 @@ namespace osu.Game.Overlays.Toolbar public partial class ToolbarBackground : Container { + private InputManager inputManager; + private Bindable showGradient { get; } = new BindableBool(); + private readonly Box gradientBackground; public ToolbarBackground() @@ -220,15 +224,26 @@ namespace osu.Game.Overlays.Toolbar }; } - protected override bool OnHover(HoverEvent e) + protected override void LoadComplete() { - gradientBackground.FadeIn(transition_time, Easing.OutQuint); - return true; + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + showGradient.BindValueChanged(_ => updateState(), true); } - protected override void OnHoverLost(HoverLostEvent e) + protected override void Update() { - gradientBackground.FadeOut(transition_time, Easing.OutQuint); + base.Update(); + showGradient.Value = Contains(inputManager.CurrentState.Mouse.Position); + } + + private void updateState() + { + if (showGradient.Value) + gradientBackground.FadeIn(transition_time, Easing.OutQuint); + else + gradientBackground.FadeOut(transition_time, Easing.OutQuint); } } From f625c5d7446144455f2366a252392467de2a1038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 23:34:33 +0100 Subject: [PATCH 3/4] Fix gradient showing when toggling toolbar with mouse above window --- osu.Game/Overlays/Toolbar/Toolbar.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index a559363bbf..dbad866f74 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -235,7 +235,11 @@ namespace osu.Game.Overlays.Toolbar protected override void Update() { base.Update(); - showGradient.Value = Contains(inputManager.CurrentState.Mouse.Position); + + var currentMousePosition = inputManager.CurrentState.Mouse.Position; + // ensure that the gradient is not shown if the mouse is above the window. + // this is relevant when the background is moving due to the toolbar being toggled. + showGradient.Value = currentMousePosition.Y >= 0 && Contains(inputManager.CurrentState.Mouse.Position); } private void updateState() From 0d70f2c0fd3d070b49c6ce4225a88bed63932392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 09:07:48 +0100 Subject: [PATCH 4/4] Use alternative workaround --- osu.Game/Overlays/Toolbar/Toolbar.cs | 54 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index dbad866f74..f21ef0ee98 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -13,7 +13,6 @@ using osuTK; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets; using osu.Framework.Input.Bindings; @@ -66,9 +65,12 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame) { + ToolbarBackground background; + HoverInterceptor interceptor; + Children = new Drawable[] { - new ToolbarBackground(), + background = new ToolbarBackground(), new GridContainer { RelativeSizeAxes = Axes.Both, @@ -181,9 +183,15 @@ namespace osu.Game.Overlays.Toolbar }, }, } + }, + interceptor = new HoverInterceptor + { + RelativeSizeAxes = Axes.Both } }; + ((IBindable)background.ShowGradient).BindTo(interceptor.ReceivedHover); + if (osuGame != null) OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); } @@ -197,8 +205,7 @@ namespace osu.Game.Overlays.Toolbar public partial class ToolbarBackground : Container { - private InputManager inputManager; - private Bindable showGradient { get; } = new BindableBool(); + public Bindable ShowGradient { get; } = new BindableBool(); private readonly Box gradientBackground; @@ -228,29 +235,42 @@ namespace osu.Game.Overlays.Toolbar { base.LoadComplete(); - inputManager = GetContainingInputManager(); - showGradient.BindValueChanged(_ => updateState(), true); - } - - protected override void Update() - { - base.Update(); - - var currentMousePosition = inputManager.CurrentState.Mouse.Position; - // ensure that the gradient is not shown if the mouse is above the window. - // this is relevant when the background is moving due to the toolbar being toggled. - showGradient.Value = currentMousePosition.Y >= 0 && Contains(inputManager.CurrentState.Mouse.Position); + ShowGradient.BindValueChanged(_ => updateState(), true); } private void updateState() { - if (showGradient.Value) + if (ShowGradient.Value) gradientBackground.FadeIn(transition_time, Easing.OutQuint); else gradientBackground.FadeOut(transition_time, Easing.OutQuint); } } + /// + /// Whenever the mouse cursor is within the bounds of the toolbar, we want the background gradient to show, for toolbar button descriptions to be legible. + /// Unfortunately we also need to ensure that the toolbar buttons handle hover, to prevent the possibility of multiple descriptions being shown + /// due to hover events passing through multiple buttons. + /// This drawable is a workaround, that when placed front-most in the toolbar, allows to see whether hover events have been propagated through it without handling them. + /// + private partial class HoverInterceptor : Drawable + { + public IBindable ReceivedHover => receivedHover; + private readonly Bindable receivedHover = new BindableBool(); + + protected override bool OnHover(HoverEvent e) + { + receivedHover.Value = true; + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + receivedHover.Value = false; + base.OnHoverLost(e); + } + } + protected override void UpdateState(ValueChangedEvent state) { bool blockShow = hiddenByUser || OverlayActivationMode.Value == OverlayActivation.Disabled;