From d98d330da20e2bced3a4d753f40c6a50f614f926 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Feb 2023 14:30:46 -0800 Subject: [PATCH 1/3] Add expected behavior test for scroll back to previous position --- .../TestSceneOverlayScrollContainer.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs index 926bc01aea..ade950e2d5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs @@ -61,6 +61,18 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("scroll to 500", () => scroll.ScrollTo(500)); AddUntilStep("scrolled to 500", () => Precision.AlmostEquals(scroll.Current, 500, 0.1f)); AddAssert("button is visible", () => scroll.Button.State == Visibility.Visible); + + AddStep("click button", () => + { + InputManager.MoveMouseTo(scroll.Button); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("button is visible", () => scroll.Button.State == Visibility.Visible); + + AddStep("user scroll down by 1", () => InputManager.ScrollVerticalBy(-1)); + + AddAssert("button is hidden", () => scroll.Button.State == Visibility.Hidden); } [Test] @@ -71,6 +83,10 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("invoke action", () => scroll.Button.Action.Invoke()); AddUntilStep("scrolled back to start", () => Precision.AlmostEquals(scroll.Current, 0, 0.1f)); + + AddStep("invoke action", () => scroll.Button.Action.Invoke()); + + AddAssert("scrolled to end", () => scroll.IsScrolledToEnd()); } [Test] @@ -85,6 +101,14 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddUntilStep("scrolled back to start", () => Precision.AlmostEquals(scroll.Current, 0, 0.1f)); + + AddStep("click button", () => + { + InputManager.MoveMouseTo(scroll.Button); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("scrolled to end", () => scroll.IsScrolledToEnd()); } [Test] @@ -97,7 +121,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("hover button", () => InputManager.MoveMouseTo(scroll.Button)); AddRepeatStep("click button", () => InputManager.Click(MouseButton.Left), 3); - AddAssert("invocation count is 1", () => invocationCount == 1); + AddAssert("invocation count is 3", () => invocationCount == 3); } private partial class TestScrollContainer : OverlayScrollContainer From dc00905f8df0b24f974315a7efdac099373f09eb Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Feb 2023 14:38:51 -0800 Subject: [PATCH 2/3] Add ability to scroll back to previous position after scrolling to top via button on overlays --- osu.Game/Overlays/OverlayScrollContainer.cs | 50 +++++++++++++++++---- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index 5bd7f014a9..8176ddb370 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,16 +31,20 @@ namespace osu.Game.Overlays /// private const int button_scroll_position = 200; - protected readonly ScrollToTopButton Button; + protected ScrollToTopButton Button; - public OverlayScrollContainer() + private readonly Bindable lastScrollTarget = new Bindable(); + + [BackgroundDependencyLoader] + private void load() { AddInternal(Button = new ScrollToTopButton { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, Margin = new MarginPadding(20), - Action = scrollToTop + Action = scrollBack, + LastScrollTarget = { BindTarget = lastScrollTarget } }); } @@ -53,13 +58,28 @@ namespace osu.Game.Overlays return; } - Button.State = Target > button_scroll_position ? Visibility.Visible : Visibility.Hidden; + Button.State = Target > button_scroll_position || lastScrollTarget.Value != null ? Visibility.Visible : Visibility.Hidden; } - private void scrollToTop() + protected override void OnUserScroll(float value, bool animated = true, double? distanceDecay = default) { - ScrollToStart(); - Button.State = Visibility.Hidden; + base.OnUserScroll(value, animated, distanceDecay); + + lastScrollTarget.Value = null; + } + + private void scrollBack() + { + if (lastScrollTarget.Value == null) + { + lastScrollTarget.Value = Target; + ScrollToStart(); + } + else + { + ScrollTo(lastScrollTarget.Value.Value); + lastScrollTarget.Value = null; + } } public partial class ScrollToTopButton : OsuHoverContainer @@ -88,6 +108,9 @@ namespace osu.Game.Overlays private readonly Container content; private readonly Box background; + private readonly SpriteIcon spriteIcon; + + public Bindable LastScrollTarget = new Bindable(); public ScrollToTopButton() : base(HoverSampleSet.ScrollToTop) @@ -113,7 +136,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both }, - new SpriteIcon + spriteIcon = new SpriteIcon { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -134,6 +157,17 @@ namespace osu.Game.Overlays flashColour = colourProvider.Light1; } + protected override void LoadComplete() + { + base.LoadComplete(); + + LastScrollTarget.BindValueChanged(target => + { + spriteIcon.RotateTo(target.NewValue != null ? 180 : 0, fade_duration, Easing.OutQuint); + TooltipText = target.NewValue != null ? CommonStrings.ButtonsBackToPrevious : CommonStrings.ButtonsBackToTop; + }, true); + } + protected override bool OnClick(ClickEvent e) { background.FlashColour(flashColour, 800, Easing.OutQuint); From fa710ae1b00dd9f618e481271b25aa2df5d558a4 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Feb 2023 14:39:34 -0800 Subject: [PATCH 3/3] Rename `ScrollToTopButton` to `ScrollBackButton` --- .../UserInterface/TestSceneOverlayScrollContainer.cs | 2 +- osu.Game/Overlays/OverlayScrollContainer.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs index ade950e2d5..77e7178c9e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Visual.UserInterface private partial class TestScrollContainer : OverlayScrollContainer { - public new ScrollToTopButton Button => base.Button; + public new ScrollBackButton Button => base.Button; } } } diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index 8176ddb370..9752e04f44 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -22,23 +22,23 @@ using osuTK.Graphics; namespace osu.Game.Overlays { /// - /// which provides . Mostly used in . + /// which provides . Mostly used in . /// public partial class OverlayScrollContainer : UserTrackingScrollContainer { /// - /// Scroll position at which the will be shown. + /// Scroll position at which the will be shown. /// private const int button_scroll_position = 200; - protected ScrollToTopButton Button; + protected ScrollBackButton Button; private readonly Bindable lastScrollTarget = new Bindable(); [BackgroundDependencyLoader] private void load() { - AddInternal(Button = new ScrollToTopButton + AddInternal(Button = new ScrollBackButton { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, @@ -82,7 +82,7 @@ namespace osu.Game.Overlays } } - public partial class ScrollToTopButton : OsuHoverContainer + public partial class ScrollBackButton : OsuHoverContainer { private const int fade_duration = 500; @@ -112,7 +112,7 @@ namespace osu.Game.Overlays public Bindable LastScrollTarget = new Bindable(); - public ScrollToTopButton() + public ScrollBackButton() : base(HoverSampleSet.ScrollToTop) { Size = new Vector2(50);