Use UserTrackingScrollContainer instead

This commit is contained in:
Dean Herbert
2021-02-02 15:16:10 +09:00
parent ed63b571d2
commit 398ab9c2c2
2 changed files with 22 additions and 12 deletions

View File

@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual.Online
protected DrawableChannel DrawableChannel => InternalChildren.OfType<DrawableChannel>().First(); protected DrawableChannel DrawableChannel => InternalChildren.OfType<DrawableChannel>().First();
protected OsuScrollContainer ScrollContainer => (OsuScrollContainer)((Container)DrawableChannel.Child).Child; protected UserTrackingScrollContainer ScrollContainer => (UserTrackingScrollContainer)((Container)DrawableChannel.Child).Child;
public FillFlowContainer FillFlow => (FillFlowContainer)ScrollContainer.Child; public FillFlowContainer FillFlow => (FillFlowContainer)ScrollContainer.Child;

View File

@ -16,6 +16,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Utils;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
namespace osu.Game.Overlays.Chat namespace osu.Game.Overlays.Chat
@ -147,8 +148,8 @@ namespace osu.Game.Overlays.Chat
// due to the scroll adjusts from old messages removal above, a scroll-to-end must be enforced, // due to the scroll adjusts from old messages removal above, a scroll-to-end must be enforced,
// to avoid making the container think the user has scrolled back up and unwantedly disable auto-scrolling. // to avoid making the container think the user has scrolled back up and unwantedly disable auto-scrolling.
if (scroll.ShouldAutoScroll || newMessages.Any(m => m is LocalMessage)) if (newMessages.Any(m => m is LocalMessage))
ScheduleAfterChildren(() => scroll.ScrollToEnd()); scroll.ScrollToEnd();
}); });
private void pendingMessageResolved(Message existing, Message updated) => Schedule(() => private void pendingMessageResolved(Message existing, Message updated) => Schedule(() =>
@ -239,7 +240,7 @@ namespace osu.Game.Overlays.Chat
/// <summary> /// <summary>
/// An <see cref="OsuScrollContainer"/> with functionality to automatically scroll whenever the maximum scrollable distance increases. /// An <see cref="OsuScrollContainer"/> with functionality to automatically scroll whenever the maximum scrollable distance increases.
/// </summary> /// </summary>
private class ChannelScrollContainer : OsuScrollContainer private class ChannelScrollContainer : UserTrackingScrollContainer
{ {
/// <summary> /// <summary>
/// The chat will be automatically scrolled to end if and only if /// The chat will be automatically scrolled to end if and only if
@ -250,21 +251,30 @@ namespace osu.Game.Overlays.Chat
private float? lastExtent; private float? lastExtent;
/// <summary> protected override void OnUserScroll(float value, bool animated = true, double? distanceDecay = default)
/// Whether this container should automatically scroll to end on the next call to <see cref="UpdateAfterChildren"/>. {
/// </summary> base.OnUserScroll(value, animated, distanceDecay);
public bool ShouldAutoScroll { get; private set; } = true; lastExtent = null;
}
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()
{ {
base.UpdateAfterChildren(); base.UpdateAfterChildren();
if ((lastExtent == null || ScrollableExtent > lastExtent) && ShouldAutoScroll) // If the user has scrolled to the bottom of the container, we should resume tracking new content.
bool cancelUserScroll = UserScrolling && IsScrolledToEnd(auto_scroll_leniency);
// If the user hasn't overridden our behaviour and there has been new content added to the container, we should update our scroll position to track it.
bool requiresScrollUpdate = !UserScrolling && (lastExtent == null || Precision.AlmostBigger(ScrollableExtent, lastExtent.Value));
if (cancelUserScroll || requiresScrollUpdate)
{
ScheduleAfterChildren(() =>
{
ScrollToEnd(); ScrollToEnd();
ShouldAutoScroll = IsScrolledToEnd(auto_scroll_leniency);
lastExtent = ScrollableExtent; lastExtent = ScrollableExtent;
});
}
} }
} }
} }