Skip to content

Commit

Permalink
fix(scrollviewer): [WASM] Make the SCP the "element which scrolls" (i…
Browse files Browse the repository at this point in the history
…nstead of the SV)
  • Loading branch information
dr1rrb committed Oct 6, 2021
1 parent d05ebc4 commit ee21a4e
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public bool CanHorizontallyScroll
#endif
// Skipping already declared property ExtentHeight
// Skipping already declared property ExtentWidth
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || false || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__NETSTD_REFERENCE__", "__MACOS__")]
public double HorizontalOffset
{
Expand All @@ -61,7 +61,7 @@ public double HorizontalOffset
}
}
#endif
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || false || __NETSTD_REFERENCE__ || false
#if __ANDROID__ || __IOS__ || NET461 || false || false || __NETSTD_REFERENCE__ || false
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__NETSTD_REFERENCE__", "__MACOS__")]
public double VerticalOffset
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal Size ScrollBarSize

public ScrollContentPresenter()
{
RegisterAsScrollPort(this);
}

private void TryRegisterEvents(ScrollBarVisibility visibility)
Expand Down Expand Up @@ -143,6 +144,10 @@ public bool CanVerticallyScroll
set { }
}

public double HorizontalOffset { get; private set; }

public double VerticalOffset { get; private set; }

Size? IScrollContentPresenter.CustomContentExtent => null;

private protected override void OnLoaded()
Expand Down Expand Up @@ -248,11 +253,16 @@ private void OnScroll(object sender, EventArgs args)
// (the SV updates mode is always sync when isIntermediate is false).
var isIntermediate = false;

(TemplatedParent as ScrollViewer)?.OnScrollInternal(
GetNativeHorizontalOffset(),
GetNativeVerticalOffset(),
isIntermediate
);
var horizontalOffset = GetNativeHorizontalOffset();
var verticalOffset = GetNativeVerticalOffset();

HorizontalOffset = horizontalOffset;
VerticalOffset = verticalOffset;

(TemplatedParent as ScrollViewer)?.OnScrollInternal(horizontalOffset, verticalOffset, isIntermediate);

ScrollOffsets = new Point(horizontalOffset, verticalOffset);
InvalidateViewport();
}

private double GetNativeHorizontalOffset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Windows.Foundation;
using Windows.UI.Xaml.Automation.Peers;
using DirectUI;
using Uno.Disposables;
Expand All @@ -17,10 +18,30 @@ partial class ScrollViewer

internal bool m_templatedParentHandlesMouseButton;

// Indicates whether ScrollViewer should ignore mouse wheel scroll events (not zoom).
internal bool ArePointerWheelEventsIgnored { get; set; } = false;
internal bool IsInManipulation => IsInDirectManipulation || m_isInConstantVelocityPan;

/// <summary>
/// Gets or set whether the <see cref="ScrollViewer"/> will allow scrolling outside of the ScrollViewer's Child bound.
/// </summary>
internal bool ForceChangeToCurrentView { get; set; } = false;
internal bool IsInDirectManipulation { get; }
internal bool TemplatedParentHandlesScrolling { get; set; }
internal Func<AutomationPeer>? AutomationPeerFactoryIndex { get; set; }

internal bool BringIntoViewport(Rect bounds,
bool skipDuringTouchContact,
bool skipAnimationWhileRunning,
bool animate)
{
#if __WASM__
return ChangeView(bounds.X, bounds.Y, null, true);
#else
return ChangeView(bounds.X, bounds.Y, null, !animate);
#endif
}

internal void SetDirectManipulationStateChangeHandler(IDirectManipulationStateChangeHandler? handler)
{
_directManipulationHandlerSubscription?.Dispose();
Expand Down
48 changes: 12 additions & 36 deletions src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#pragma warning disable CS0067
#endif

#if !UNO_HAS_MANAGED_SCROLL_PRESENTER && !__WASM__
#define IS_SCROLL_PORT
#endif

#nullable enable

using System;
Expand Down Expand Up @@ -119,7 +123,7 @@ public ScrollViewer()
{
DefaultStyleKey = typeof(ScrollViewer);

#if !UNO_HAS_MANAGED_SCROLL_PRESENTER
#if IS_SCROLL_PORT
// On Skia, the Scrolling is managed by the ScrollContentPresenter (as UWP), which is flagged as IsScrollPort.
// Note: We should still add support for the zoom factor ... which is not yet supported on Skia.
// Note 2: This as direct consequences in UIElement.GetTransform and VisualTreeHelper.SearchDownForTopMostElementAt
Expand Down Expand Up @@ -634,7 +638,6 @@ public double HorizontalOffset
/// </summary>
internal bool ComputedIsVerticalScrollEnabled { get; private set; } = false;


internal double MinHorizontalOffset => 0;

internal double MinVerticalOffset => 0;
Expand Down Expand Up @@ -1305,7 +1308,7 @@ private void Update(bool isIntermediate)

UpdatePartial(isIntermediate);

#if !UNO_HAS_MANAGED_SCROLL_PRESENTER
#if IS_SCROLL_PORT
// Effective viewport support
ScrollOffsets = new Point(_pendingHorizontalOffset, _pendingVerticalOffset);
InvalidateViewport();
Expand All @@ -1316,6 +1319,12 @@ private void Update(bool isIntermediate)

partial void UpdatePartial(bool isIntermediate);

public void ScrollToHorizontalOffset(double offset)
=> ChangeView(offset, null, null, false);

public void ScrollToVerticalOffset(double offset)
=> ChangeView(null, offset, null, false);

/// <summary>
/// Causes the ScrollViewer to load a new view into the viewport using the specified offsets and zoom factor, and optionally disables scrolling animation.
/// </summary>
Expand Down Expand Up @@ -1493,38 +1502,5 @@ private void HideScrollBarSeparator(object sender, PointerRoutedEventArgs e) //
}
}
#endregion

public void ScrollToHorizontalOffset(double offset)
{
_ = ChangeView(offset, null, null, false);
}

public void ScrollToVerticalOffset(double offset)
{
_ = ChangeView(null, offset, null, false);
}

// Indicates whether ScrollViewer should ignore mouse wheel scroll events (not zoom).
public bool ArePointerWheelEventsIgnored { get; set; } = false;

internal bool BringIntoViewport(Rect bounds,
bool skipDuringTouchContact,
bool skipAnimationWhileRunning,
bool animate)
{
#if __WASM__
return ChangeView(bounds.X, bounds.Y, null, true);
#else
return ChangeView(bounds.X, bounds.Y, null, !animate);
#endif
}

internal bool IsInManipulation => IsInDirectManipulation || m_isInConstantVelocityPan;

/// <summary>
/// Gets or set whether the <see cref="ScrollViewer"/> will allow scrolling outside of the ScrollViewer's Child bound.
/// </summary>
internal bool ForceChangeToCurrentView { get; set; } = false;

}
}
4 changes: 2 additions & 2 deletions src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ private static (UIElement? element, Branch? stale) SearchDownForTopMostElementAt
renderingBounds = parentToElement.Transform(renderingBounds);
}

#if !UNO_HAS_MANAGED_SCROLL_PRESENTER
#if !UNO_HAS_MANAGED_SCROLL_PRESENTER && !__WASM__
// On Skia, the Scrolling is managed by the ScrollContentPresenter (as UWP), which is flagged as IsScrollPort.
// Note: We should still add support for the zoom factor ... which is not yet supported on Skia.
if (element is ScrollViewer sv)
Expand All @@ -410,7 +410,7 @@ private static (UIElement? element, Branch? stale) SearchDownForTopMostElementAt
else
#endif
#if !__MACOS__ // On macOS the SCP is using RenderTransforms for scrolling which has already been included.
if (element.IsScrollPort)
if (element.IsScrollPort) // Managed SCP or custom scroller
{
posRelToElement.X += element.ScrollOffsets.X;
posRelToElement.Y += element.ScrollOffsets.Y;
Expand Down
4 changes: 2 additions & 2 deletions src/Uno.UI/UI/Xaml/UIElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ internal static Matrix3x2 GetTransform(UIElement from, UIElement to)
offsetY = layoutSlot.Y;
}

#if !UNO_HAS_MANAGED_SCROLL_PRESENTER
#if !UNO_HAS_MANAGED_SCROLL_PRESENTER && !__WASM__
// On Skia, the Scrolling is managed by the ScrollContentPresenter (as UWP), which is flagged as IsScrollPort.
// Note: We should still add support for the zoom factor ... which is not yet supported on Skia.
if (elt is ScrollViewer sv
Expand Down Expand Up @@ -372,7 +372,7 @@ internal static Matrix3x2 GetTransform(UIElement from, UIElement to)
#if !__MACOS__ // On macOS the SCP is using RenderTransforms for scrolling which has already been included.
if (elt.IsScrollPort
// Don't adjust for scroll offsets if it's the scroll port itself calling TransformToVisual, only for ancestors
&& elt != from) // Custom scroller
&& elt != from) // Managed SCP or custom scroller
{
offsetX -= elt.ScrollOffsets.X;
offsetY -= elt.ScrollOffsets.Y;
Expand Down

0 comments on commit ee21a4e

Please sign in to comment.