Skip to content

Commit

Permalink
fix(listview): [WASM] [Skia] Correct scroll offsets if necessary when…
Browse files Browse the repository at this point in the history
… scrolling upwards in list
  • Loading branch information
davidjohnoliver committed Oct 18, 2021
1 parent 5e8bce5 commit cd74fd9
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/Uno.UI/DirectUI/DoubleUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,12 @@ public static bool AreWithinTolerance(
{
return LessThanOrClose(Math.Abs(a - b), tolerance);
}

// Returns whether or not the double is "close" to 0. Same as AreClose(double,
// 0), but this is faster.
public static bool IsZero(double value)
{
return Math.Abs(value) < 10.0 * double.Epsilon;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Uno.UI.Extensions;
using System.Collections.Specialized;
using Uno.UI.Xaml.Controls;
using DirectUI;
#if __MACOS__
using AppKit;
#elif __IOS__
Expand Down Expand Up @@ -168,6 +169,9 @@ private double ExtendedViewportEnd

private bool ShouldMeasuredBreadthStretch => ShouldBreadthStretch && GetBreadth(_availableSize) < double.MaxValue / 2;

// TODO: this should be adjusted when header, group headers etc are implemented
private double PositionOfFirstElement => 0;

internal void Initialize(_Panel owner)
{
OwnerPanel = owner ?? throw new ArgumentNullException(nameof(owner));
Expand Down Expand Up @@ -357,6 +361,8 @@ private void UpdateLayout(double? extentAdjustment, bool isScroll)
UnfillLayout(extentAdjustment ?? 0);
FillLayout(extentAdjustment ?? 0);

CorrectForEstimationErrors();

if (this.Log().IsEnabled(LogLevel.Debug))
{
this.Log().LogDebug($"Called {GetMethodTag()}, {GetDebugInfo()} extentAdjustment={extentAdjustment}");
Expand Down Expand Up @@ -489,6 +495,42 @@ private void ScrapLine(Line line)
}
}

/// <summary>
/// Item positions relative to the start of the panel are an estimate, which may be incorrect eg if unmaterialized items were added/removed
/// or had their databound heights changed. Here we try to correct it.
/// </summary>
void CorrectForEstimationErrors()
{
if (GetFirstMaterializedLine() is { } firstLine)
{
var neededCorrection = 0d;
var start = GetMeasuredStart(firstLine.FirstView);
if (firstLine.FirstItemFlat == 0)
{
neededCorrection = -start;
}
else if (start < PositionOfFirstElement)
{
// TODO: this is crude, the better approach (and in line with Windows) would be to estimate the position of the element, and use that
neededCorrection = -start;
}

// If the needed correction is non-zero, run through all our elements and apply the correction to their bounds
if (!DoubleUtil.IsZero(neededCorrection))
{
foreach (var line in _materializedLines)
{
foreach (var item in line.Items)
{
var bounds = GetBoundsForElement(item.container);
IncrementStart(ref bounds, neededCorrection);
SetBounds(item.container, bounds);
}
}
}
}
}

/// <summary>
/// If there are pending collection changes, update values and prepare the layouter accordingly.
/// </summary>
Expand Down Expand Up @@ -971,6 +1013,17 @@ protected void SetBreadth(ref Rect rect, double breadth)
}
}

private void IncrementStart(ref Rect rect, double startIncrement)
{
if (ScrollOrientation == Orientation.Vertical)
{
rect.Y += startIncrement;
}
else
{
rect.X += startIncrement;
}
}

private double GetActualBreadth(FrameworkElement view) => ScrollOrientation == Orientation.Vertical ?
view.ActualWidth :
Expand Down

0 comments on commit cd74fd9

Please sign in to comment.