Resolve scroll animation/position issues

This commit is contained in:
Dean Herbert
2017-12-18 02:23:03 +09:00
parent 54cc6fadf9
commit 19643ba5e6

View File

@ -74,7 +74,8 @@ namespace osu.Game.Screens.Select
{ {
root = newRoot; root = newRoot;
scrollableContent.Clear(false); scrollableContent.Clear(false);
yPositionsCache.Invalidate(); itemsCache.Invalidate();
scrollPositionCache.Invalidate();
BeatmapSetsChanged?.Invoke(); BeatmapSetsChanged?.Invoke();
}); });
}); });
@ -82,7 +83,8 @@ namespace osu.Game.Screens.Select
} }
private readonly List<float> yPositions = new List<float>(); private readonly List<float> yPositions = new List<float>();
private Cached yPositionsCache = new Cached(); private Cached itemsCache = new Cached();
private Cached scrollPositionCache = new Cached();
private readonly Container<DrawableCarouselItem> scrollableContent; private readonly Container<DrawableCarouselItem> scrollableContent;
@ -114,7 +116,7 @@ namespace osu.Game.Screens.Select
return; return;
root.RemoveChild(existingSet); root.RemoveChild(existingSet);
yPositionsCache.Invalidate(); itemsCache.Invalidate();
} }
public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet)
@ -130,7 +132,7 @@ namespace osu.Game.Screens.Select
if (newSet == null) if (newSet == null)
{ {
yPositionsCache.Invalidate(); itemsCache.Invalidate();
SelectNext(); SelectNext();
return; return;
} }
@ -143,7 +145,7 @@ namespace osu.Game.Screens.Select
if (hadSelection) if (hadSelection)
select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet); select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet);
yPositionsCache.Invalidate(); itemsCache.Invalidate();
} }
public void SelectBeatmap(BeatmapInfo beatmap) public void SelectBeatmap(BeatmapInfo beatmap)
@ -278,9 +280,16 @@ namespace osu.Game.Screens.Select
FilterTask = null; FilterTask = null;
root.Filter(activeCriteria); root.Filter(activeCriteria);
yPositionsCache.Invalidate(); itemsCache.Invalidate();
if (scroll) ScrollToSelected(false); if (scroll)
{
Schedule(() =>
{
updateItems(false);
updateScrollPosition(false);
});
}
} }
FilterTask?.Cancel(); FilterTask?.Cancel();
@ -294,7 +303,7 @@ namespace osu.Game.Screens.Select
private float? scrollTarget; private float? scrollTarget;
public void ScrollToSelected(bool animated = true) => Schedule(() => { if (scrollTarget != null) ScrollTo(scrollTarget.Value, animated); }); public void ScrollToSelected() => scrollPositionCache.Invalidate();
private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet) private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet)
{ {
@ -318,8 +327,9 @@ namespace osu.Game.Screens.Select
{ {
selectedBeatmapSet = set; selectedBeatmapSet = set;
SelectionChanged?.Invoke(c.Beatmap); SelectionChanged?.Invoke(c.Beatmap);
yPositionsCache.Invalidate();
Schedule(() => ScrollToSelected()); itemsCache.Invalidate();
scrollPositionCache.Invalidate();
} }
}; };
} }
@ -337,8 +347,10 @@ namespace osu.Game.Screens.Select
/// Computes the target Y positions for every item in the carousel. /// Computes the target Y positions for every item in the carousel.
/// </summary> /// </summary>
/// <returns>The Y position of the currently selected item.</returns> /// <returns>The Y position of the currently selected item.</returns>
private void computeYPositions(bool animated = true) private void updateItems(bool animated = true)
{ {
Items = root.Drawables.ToList();
yPositions.Clear(); yPositions.Clear();
float currentY = DrawHeight / 2; float currentY = DrawHeight / 2;
@ -395,13 +407,19 @@ namespace osu.Game.Screens.Select
currentY += DrawHeight / 2; currentY += DrawHeight / 2;
scrollableContent.Height = currentY; scrollableContent.Height = currentY;
yPositionsCache.Validate(); if (selectedBeatmapSet?.Filtered.Value == true)
{
selectedBeatmapSet = null;
SelectionChanged?.Invoke(null);
} }
private void noSelection() itemsCache.Validate();
}
private void updateScrollPosition(bool animated = true)
{ {
if (root.Children == null || root.Children.All(c => c.Filtered)) if (scrollTarget != null) ScrollTo(scrollTarget.Value, animated);
SelectionChanged?.Invoke(null); scrollPositionCache.Validate();
} }
private void select(CarouselItem item) private void select(CarouselItem item)
@ -444,15 +462,11 @@ namespace osu.Game.Screens.Select
{ {
base.Update(); base.Update();
// todo: scheduled scrolls... if (!itemsCache.IsValid)
if (!yPositionsCache.IsValid) updateItems();
{
Items = root.Drawables.ToList();
computeYPositions();
if (selectedBeatmapSet != null && beatmapSets.All(s => s.Filtered)) if (!scrollPositionCache.IsValid)
SelectionChanged?.Invoke(null); updateScrollPosition();
}
float drawHeight = DrawHeight; float drawHeight = DrawHeight;
@ -509,7 +523,7 @@ namespace osu.Game.Screens.Select
// this is not actually useful right now, but once we have groups may well be. // this is not actually useful right now, but once we have groups may well be.
if (notVisibleCount > 50) if (notVisibleCount > 50)
yPositionsCache.Invalidate(); itemsCache.Invalidate();
// Update externally controlled state of currently visible items // Update externally controlled state of currently visible items
// (e.g. x-offset and opacity). // (e.g. x-offset and opacity).