Skip to content

Commit bc4949e

Browse files
authored
[Fabric] Enable ScrollView touch scrolling (#13664)
* [Fabric] Enable ScrolView touch scrolling * Change files * format * typo
1 parent a4e263c commit bc4949e

File tree

7 files changed

+70
-13
lines changed

7 files changed

+70
-13
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "[Fabric] Enable ScrollView touch scrolling",
4+
"packageName": "react-native-windows",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/Composition.Input.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace Microsoft.ReactNative.Composition.Input
106106
UInt64 Timestamp { get; };
107107
PointerPoint GetOffsetPoint(
108108
Windows.Foundation.Point offset);
109+
Microsoft.UI.Input.PointerPoint Inner { get; };
109110
};
110111

111112
runtimeclass PointerRoutedEventArgs : RoutedEventArgs

vnext/Microsoft.ReactNative/CompositionSwitcher.idl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "NamespaceRedirect.h"
55
#include "DocString.h"
6+
import "Composition.Input.idl";
67

78
namespace Microsoft.ReactNative.Composition.Experimental
89
{
@@ -112,6 +113,8 @@ namespace Microsoft.ReactNative.Composition.Experimental
112113
Windows.Foundation.Numerics.Vector3 ScrollPosition { get; };
113114
void ScrollBy(Windows.Foundation.Numerics.Vector3 offset, Boolean animate);
114115
void TryUpdatePosition(Windows.Foundation.Numerics.Vector3 position, Boolean animate);
116+
void OnPointerPressed(Microsoft.ReactNative.Composition.Input.PointerRoutedEventArgs args);
117+
Boolean Horizontal;
115118
}
116119

117120
[webhosthidden]

vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,10 @@ bool PointerPoint::IsPointerMessage(uint32_t message) const noexcept {
637637
return (message >= WM_POINTERFIRST && message <= WM_POINTERLAST);
638638
}
639639

640+
winrt::Microsoft::UI::Input::PointerPoint PointerPoint::Inner() const noexcept {
641+
return m_sysPointerPoint;
642+
}
643+
640644
PointerRoutedEventArgs::PointerRoutedEventArgs(
641645
const winrt::Microsoft::ReactNative::ReactContext &context,
642646
facebook::react::Tag tag,

vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ struct PointerPoint : PointerPointT<PointerPoint> {
198198
uint64_t Timestamp() const noexcept;
199199
winrt::Microsoft::ReactNative::Composition::Input::PointerPoint GetOffsetPoint(
200200
const winrt::Windows::Foundation::Point &offset) const noexcept;
201+
winrt::Microsoft::UI::Input::PointerPoint Inner() const noexcept;
201202

202203
private:
203204
bool IsPointerMessage(uint32_t message) const noexcept;

vnext/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <Windows.Graphics.Interop.h>
1414
#include <windows.ui.composition.interop.h>
15+
#include <winrt/Microsoft.ReactNative.Composition.Input.h>
1516
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>
1617
#include <winrt/Windows.UI.Composition.h>
1718
#include <winrt/Windows.UI.Composition.interactions.h>
@@ -744,14 +745,9 @@ struct CompScrollerVisual : winrt::implements<
744745
m_interactionTracker.MaxScale(1.0);
745746

746747
m_visualInteractionSource = TTypeRedirects::VisualInteractionSource::Create(m_visual);
747-
748-
m_visualInteractionSource.PositionXSourceMode(TTypeRedirects::InteractionSourceMode::EnabledWithInertia);
749-
m_visualInteractionSource.PositionYSourceMode(TTypeRedirects::InteractionSourceMode::EnabledWithInertia);
750748
m_visualInteractionSource.ScaleSourceMode(TTypeRedirects::InteractionSourceMode::Disabled);
751-
752-
m_visualInteractionSource.ManipulationRedirectionMode(
753-
TTypeRedirects::VisualInteractionSourceRedirectionMode::CapableTouchpadAndPointerWheel);
754749
m_interactionTracker.InteractionSources().Add(m_visualInteractionSource);
750+
UpdateInteractionModes();
755751

756752
auto positionExpression = compositor.CreateExpressionAnimation(L"-tracker.Position");
757753
positionExpression.SetReferenceParameter(L"tracker", m_interactionTracker);
@@ -762,6 +758,44 @@ struct CompScrollerVisual : winrt::implements<
762758
return m_visual;
763759
}
764760

761+
void OnPointerPressed(
762+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {
763+
if constexpr (std::is_same_v<TTypeRedirects, MicrosoftTypeRedirects>) {
764+
auto pointerDeviceType = args.Pointer().PointerDeviceType();
765+
if (pointerDeviceType == winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Touch) {
766+
m_visualInteractionSource.TryRedirectForManipulation(args.GetCurrentPoint(args.OriginalSource()).Inner());
767+
}
768+
}
769+
}
770+
771+
bool Horizontal() const noexcept {
772+
return m_horizontal;
773+
}
774+
775+
void Horizontal(bool value) noexcept {
776+
m_horizontal = value;
777+
778+
UpdateInteractionModes();
779+
}
780+
781+
void UpdateInteractionModes() noexcept {
782+
if (m_isScrollEnabled) {
783+
m_visualInteractionSource.PositionXSourceMode(
784+
m_horizontal ? TTypeRedirects::InteractionSourceMode::EnabledWithInertia
785+
: TTypeRedirects::InteractionSourceMode::Disabled);
786+
m_visualInteractionSource.PositionYSourceMode(
787+
m_horizontal ? TTypeRedirects::InteractionSourceMode::Disabled
788+
: TTypeRedirects::InteractionSourceMode::EnabledWithInertia);
789+
m_visualInteractionSource.ManipulationRedirectionMode(
790+
TTypeRedirects::VisualInteractionSourceRedirectionMode::CapableTouchpadAndPointerWheel);
791+
} else {
792+
m_visualInteractionSource.PositionXSourceMode(TTypeRedirects::InteractionSourceMode::Disabled);
793+
m_visualInteractionSource.PositionYSourceMode(TTypeRedirects::InteractionSourceMode::Disabled);
794+
m_visualInteractionSource.ManipulationRedirectionMode(
795+
TTypeRedirects::VisualInteractionSourceRedirectionMode::Off);
796+
}
797+
}
798+
765799
void InsertAt(
766800
const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual,
767801
uint32_t index) noexcept {
@@ -796,13 +830,8 @@ struct CompScrollerVisual : winrt::implements<
796830
}
797831

798832
void ScrollEnabled(bool isScrollEnabled) noexcept {
799-
if (isScrollEnabled) {
800-
m_visualInteractionSource.ManipulationRedirectionMode(
801-
TTypeRedirects::VisualInteractionSourceRedirectionMode::CapableTouchpadAndPointerWheel);
802-
} else {
803-
m_visualInteractionSource.ManipulationRedirectionMode(
804-
TTypeRedirects::VisualInteractionSourceRedirectionMode::Off);
805-
}
833+
m_isScrollEnabled = isScrollEnabled;
834+
UpdateInteractionModes();
806835
}
807836

808837
void Opacity(float opacity) noexcept {
@@ -970,6 +999,8 @@ struct CompScrollerVisual : winrt::implements<
970999
0});
9711000
}
9721001

1002+
bool m_isScrollEnabled{true};
1003+
bool m_horizontal{false};
9731004
bool m_inertia{false};
9741005
bool m_custom{false};
9751006
winrt::Windows::Foundation::Numerics::float3 m_targetPosition;

vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,10 @@ void ScrollViewComponentView::updateProps(
749749
m_horizontalScrollbarComponent->UpdateColorForScrollBarRegions();
750750
m_verticalScrollbarComponent->UpdateColorForScrollBarRegions();
751751
}
752+
753+
if (!oldProps || oldViewProps.horizontal != newViewProps.horizontal) {
754+
m_scrollVisual.Horizontal(newViewProps.horizontal);
755+
}
752756
}
753757

754758
void ScrollViewComponentView::updateState(
@@ -886,6 +890,12 @@ void ScrollViewComponentView::OnPointerPressed(
886890
m_verticalScrollbarComponent->OnPointerPressed(args);
887891
m_horizontalScrollbarComponent->OnPointerPressed(args);
888892
Super::OnPointerPressed(args);
893+
894+
if (!args.Handled()) {
895+
auto f = args.Pointer();
896+
auto g = f.PointerDeviceType();
897+
m_scrollVisual.OnPointerPressed(args);
898+
}
889899
}
890900

891901
void ScrollViewComponentView::OnPointerReleased(

0 commit comments

Comments
 (0)