mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 00:53:10 +08:00
Merge pull request #22743 from Joehuu/scroll-back-to-previous
Add ability to scroll back to previous position after scrolling to top via button on overlays
This commit is contained in:
commit
bd11d5d29a
@ -61,6 +61,18 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("scroll to 500", () => scroll.ScrollTo(500));
|
AddStep("scroll to 500", () => scroll.ScrollTo(500));
|
||||||
AddUntilStep("scrolled to 500", () => Precision.AlmostEquals(scroll.Current, 500, 0.1f));
|
AddUntilStep("scrolled to 500", () => Precision.AlmostEquals(scroll.Current, 500, 0.1f));
|
||||||
AddAssert("button is visible", () => scroll.Button.State == Visibility.Visible);
|
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]
|
[Test]
|
||||||
@ -71,6 +83,10 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("invoke action", () => scroll.Button.Action.Invoke());
|
AddStep("invoke action", () => scroll.Button.Action.Invoke());
|
||||||
|
|
||||||
AddUntilStep("scrolled back to start", () => Precision.AlmostEquals(scroll.Current, 0, 0.1f));
|
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]
|
[Test]
|
||||||
@ -85,6 +101,14 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("scrolled back to start", () => Precision.AlmostEquals(scroll.Current, 0, 0.1f));
|
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]
|
[Test]
|
||||||
@ -97,12 +121,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("hover button", () => InputManager.MoveMouseTo(scroll.Button));
|
AddStep("hover button", () => InputManager.MoveMouseTo(scroll.Button));
|
||||||
AddRepeatStep("click button", () => InputManager.Click(MouseButton.Left), 3);
|
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
|
private partial class TestScrollContainer : OverlayScrollContainer
|
||||||
{
|
{
|
||||||
public new ScrollToTopButton Button => base.Button;
|
public new ScrollBackButton Button => base.Button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -21,25 +22,29 @@ using osuTK.Graphics;
|
|||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="UserTrackingScrollContainer"/> which provides <see cref="ScrollToTopButton"/>. Mostly used in <see cref="FullscreenOverlay{T}"/>.
|
/// <see cref="UserTrackingScrollContainer"/> which provides <see cref="ScrollBackButton"/>. Mostly used in <see cref="FullscreenOverlay{T}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class OverlayScrollContainer : UserTrackingScrollContainer
|
public partial class OverlayScrollContainer : UserTrackingScrollContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scroll position at which the <see cref="ScrollToTopButton"/> will be shown.
|
/// Scroll position at which the <see cref="ScrollBackButton"/> will be shown.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int button_scroll_position = 200;
|
private const int button_scroll_position = 200;
|
||||||
|
|
||||||
protected readonly ScrollToTopButton Button;
|
protected ScrollBackButton Button;
|
||||||
|
|
||||||
public OverlayScrollContainer()
|
private readonly Bindable<float?> lastScrollTarget = new Bindable<float?>();
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
AddInternal(Button = new ScrollToTopButton
|
AddInternal(Button = new ScrollBackButton
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
Margin = new MarginPadding(20),
|
Margin = new MarginPadding(20),
|
||||||
Action = scrollToTop
|
Action = scrollBack,
|
||||||
|
LastScrollTarget = { BindTarget = lastScrollTarget }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,16 +58,31 @@ namespace osu.Game.Overlays
|
|||||||
return;
|
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();
|
base.OnUserScroll(value, animated, distanceDecay);
|
||||||
Button.State = Visibility.Hidden;
|
|
||||||
|
lastScrollTarget.Value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class ScrollToTopButton : OsuHoverContainer
|
private void scrollBack()
|
||||||
|
{
|
||||||
|
if (lastScrollTarget.Value == null)
|
||||||
|
{
|
||||||
|
lastScrollTarget.Value = Target;
|
||||||
|
ScrollToStart();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScrollTo(lastScrollTarget.Value.Value);
|
||||||
|
lastScrollTarget.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ScrollBackButton : OsuHoverContainer
|
||||||
{
|
{
|
||||||
private const int fade_duration = 500;
|
private const int fade_duration = 500;
|
||||||
|
|
||||||
@ -88,8 +108,11 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
private readonly Container content;
|
private readonly Container content;
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
private readonly SpriteIcon spriteIcon;
|
||||||
|
|
||||||
public ScrollToTopButton()
|
public Bindable<float?> LastScrollTarget = new Bindable<float?>();
|
||||||
|
|
||||||
|
public ScrollBackButton()
|
||||||
: base(HoverSampleSet.ScrollToTop)
|
: base(HoverSampleSet.ScrollToTop)
|
||||||
{
|
{
|
||||||
Size = new Vector2(50);
|
Size = new Vector2(50);
|
||||||
@ -113,7 +136,7 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both
|
RelativeSizeAxes = Axes.Both
|
||||||
},
|
},
|
||||||
new SpriteIcon
|
spriteIcon = new SpriteIcon
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -134,6 +157,17 @@ namespace osu.Game.Overlays
|
|||||||
flashColour = colourProvider.Light1;
|
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)
|
protected override bool OnClick(ClickEvent e)
|
||||||
{
|
{
|
||||||
background.FlashColour(flashColour, 800, Easing.OutQuint);
|
background.FlashColour(flashColour, 800, Easing.OutQuint);
|
||||||
|
Loading…
Reference in New Issue
Block a user