Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScrollView snap point properties #2443

Merged
merged 8 commits into from
May 16, 2019
4 changes: 1 addition & 3 deletions vnext/ReactUWP/Base/UwpReactInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@

#include <tuple>

using namespace winrt;

namespace {

struct UwpDevSettings
Expand Down Expand Up @@ -219,7 +217,7 @@ void UwpReactInstance::Start(const std::shared_ptr<IReactInstance>& spThis, cons
assert(m_uiDispatcher == nullptr && m_defaultNativeThread == nullptr && m_jsThread == nullptr && m_initThread == nullptr && m_instanceWrapper == nullptr);

m_started = true;
m_uiDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread().Dispatcher();
m_uiDispatcher = winrt::CoreWindow::GetForCurrentThread().Dispatcher();
StephenLPeters marked this conversation as resolved.
Show resolved Hide resolved
m_defaultNativeThread = std::make_shared<react::uwp::UIMessageQueueThread>(m_uiDispatcher);

// Objects that must be created on the UI thread
Expand Down
4 changes: 4 additions & 0 deletions vnext/ReactUWP/ReactUWP.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@
<ClInclude Include="Views\DatePickerViewManager.h" />
<ClInclude Include="Views\FlyoutViewManager.h" />
<ClInclude Include="Views\ImageViewManager.h" />
<ClInclude Include="Views\Impl\ScrollViewUWPImplementation.h" />
<ClInclude Include="Views\Impl\SnapPointManagingContentControl.h" />
<ClInclude Include="Views\PickerViewManager.h" />
<ClInclude Include="Views\PopupViewManager.h" />
<ClInclude Include="Views\RawTextViewManager.h" />
Expand Down Expand Up @@ -263,6 +265,8 @@
<ClCompile Include="Views\FlyoutViewManager.cpp" />
<ClCompile Include="Views\FrameworkElementViewManager.cpp" />
<ClCompile Include="Views\ImageViewManager.cpp" />
<ClCompile Include="Views\Impl\ScrollViewUWPImplementation.cpp" />
<ClCompile Include="Views\Impl\SnapPointManagingContentControl.cpp" />
<ClCompile Include="Views\PickerViewManager.cpp" />
<ClCompile Include="Views\PopupViewManager.cpp" />
<ClCompile Include="Views\RawTextViewManager.cpp" />
Expand Down
15 changes: 15 additions & 0 deletions vnext/ReactUWP/ReactUWP.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@
<ClCompile Include="Views\FlyoutViewManager.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="Views\Impl\ScrollViewUWPImplementation.cpp">
<Filter>Views\Impl</Filter>
</ClCompile>
<ClCompile Include="SnapPointManagingContentControl.cpp">
<Filter>Views\Impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Modules\DeviceInfoModule.h">
Expand Down Expand Up @@ -412,6 +418,12 @@
<ClInclude Include="Views\FlyoutViewManager.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="Views\Impl\ScrollViewUWPImplementation.h">
<Filter>Views\Impl</Filter>
</ClInclude>
<ClInclude Include="SnapPointManagingContentControl.h">
<Filter>Views\Impl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="EndPoints\dll\react-native-uwp.arm.def">
Expand Down Expand Up @@ -537,6 +549,9 @@
<Filter Include="Views\cppwinrt">
<UniqueIdentifier>{4dbf6aed-54f8-4ebd-b99d-667a4b380d8a}</UniqueIdentifier>
</Filter>
<Filter Include="Views\Impl">
<UniqueIdentifier>{101c2d4a-d343-4771-969f-29af0c9f46b2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<MidlRT Include="ABI\idl\Module.idl">
Expand Down
128 changes: 128 additions & 0 deletions vnext/ReactUWP/Views/Impl/ScrollViewUWPImplementation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include "pch.h"

#include "ScrollViewUWPImplementation.h"

namespace react {
namespace uwp {

ScrollViewUWPImplementation::ScrollViewUWPImplementation(const winrt::ScrollViewer& scrollViewer)
{
assert(scrollViewer);
const auto scrollViewContent = scrollViewer.Content();
assert(scrollViewContent);
const auto snapPointManager = scrollViewContent.as<SnapPointManagingContentControl>();
assert(snapPointManager);
assert(snapPointManager->Content().as<winrt::StackPanel>());

m_scrollViewer = winrt::make_weak(scrollViewer);
}

void ScrollViewUWPImplementation::ConvertScrollViewer(const winrt::ScrollViewer& scrollViewer)
{
if (scrollViewer)
{
const auto snapPointManager = new SnapPointManagingContentControl();
snapPointManager->Content(winrt::StackPanel{});

scrollViewer.Content(*snapPointManager);
}
}

void ScrollViewUWPImplementation::AddView(const XamlView& child, uint32_t index)
{
const auto contentCollection = ScrollViewerContent().Children();
assert(index <= contentCollection.Size());
contentCollection.InsertAt(index, child.as<winrt::UIElement>());
}

void ScrollViewUWPImplementation::RemoveAllChildren()
{
ScrollViewerContent().Children().Clear();
}

void ScrollViewUWPImplementation::RemoveChildAt(uint32_t index)
{
const auto contentCollection = ScrollViewerContent().Children();
assert(index < contentCollection.Size());
contentCollection.RemoveAt(index);
}

void ScrollViewUWPImplementation::SetHorizontal(bool horizontal)
{
ScrollViewerSnapPointManager()->SetHorizontal(horizontal);
}

void ScrollViewUWPImplementation::SnapToInterval(float interval)
{
ScrollViewerSnapPointManager()->SnapToInterval(interval);
}

void ScrollViewUWPImplementation::SnapToOffsets(const winrt::IVectorView<float>& offsets)
{
ScrollViewerSnapPointManager()->SnapToOffsets(offsets);
}

void ScrollViewUWPImplementation::UpdateScrollableSize()
{
if (const auto scrollViewer = m_scrollViewer.get())
{
switch (scrollViewer.HorizontalSnapPointsAlignment())
{
case winrt::SnapPointsAlignment::Near:
ScrollViewerSnapPointManager()->SetWidthBounds(0.0f, static_cast<float>(scrollViewer.ScrollableWidth()));
break;
case winrt::SnapPointsAlignment::Center:
ScrollViewerSnapPointManager()->SetWidthBounds(static_cast<float>(scrollViewer.ActualWidth() / 2.0f), static_cast<float>(scrollViewer.ScrollableWidth() + (scrollViewer.ActualWidth() / 2.0f)));
break;
case winrt::SnapPointsAlignment::Far:
ScrollViewerSnapPointManager()->SetWidthBounds(static_cast<float>(scrollViewer.ActualWidth()), static_cast<float>(scrollViewer.ScrollableWidth() + scrollViewer.ActualWidth()));
break;
}

switch (scrollViewer.VerticalSnapPointsAlignment())
{
case winrt::SnapPointsAlignment::Near:
ScrollViewerSnapPointManager()->SetHeightBounds(0.0f, static_cast<float>(scrollViewer.ScrollableHeight()));
break;
case winrt::SnapPointsAlignment::Center:
ScrollViewerSnapPointManager()->SetHeightBounds(static_cast<float>(scrollViewer.ActualHeight() / 2.0f), static_cast<float>(scrollViewer.ScrollableHeight() + (scrollViewer.ActualHeight() / 2.0f)));
break;
case winrt::SnapPointsAlignment::Far:
ScrollViewerSnapPointManager()->SetHeightBounds(static_cast<float>(scrollViewer.ActualHeight()), static_cast<float>(scrollViewer.ScrollableHeight() + scrollViewer.ActualHeight()));
break;
}
}
}

winrt::ScrollViewer ScrollViewUWPImplementation::ScrollViewer()
{
return m_scrollViewer.get();
}

// privates //

winrt::com_ptr<SnapPointManagingContentControl>ScrollViewUWPImplementation::ScrollViewerSnapPointManager()
{
if (const auto scrollViewer = m_scrollViewer.get())
{
if (const auto content = scrollViewer.Content())
{
return content.as<SnapPointManagingContentControl>();
}
}
return nullptr;
}

winrt::StackPanel ScrollViewUWPImplementation::ScrollViewerContent()
{
if (const auto snapPointManagingContentControl = ScrollViewerSnapPointManager())
{
if (const auto content = snapPointManagingContentControl->Content())
{
return content.as<winrt::StackPanel>();
}
}
return nullptr;
}

} }
52 changes: 52 additions & 0 deletions vnext/ReactUWP/Views/Impl/ScrollViewUWPImplementation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "pch.h"

#include "SnapPointManagingContentControl.h"

#include <Utils/PropertyUtils.h>
#include <Utils/ValueUtils.h>

#include <IReactInstance.h>

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>

namespace winrt {
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
}

namespace react {
namespace uwp {

class ScrollViewUWPImplementation
{
public:
ScrollViewUWPImplementation(const winrt::ScrollViewer& scrollViewer);
static void ConvertScrollViewer(const winrt::ScrollViewer& scrollViewer);

void AddView(const XamlView& child, uint32_t index);
void RemoveAllChildren();
void RemoveChildAt(uint32_t index);

void SetHorizontal(bool isHorizontal);
void SnapToInterval(float interval);
void SnapToOffsets(const winrt::IVectorView<float>& offsets);

void UpdateScrollableSize();

winrt::ScrollViewer ScrollViewer();
winrt::com_ptr<SnapPointManagingContentControl> ScrollViewerSnapPointManager();

private:
winrt::StackPanel ScrollViewerContent();

winrt::weak_ref<winrt::ScrollViewer> m_scrollViewer{};
};

} }
Loading