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

Add initial Windows implementation. #1409

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Check [getting started](https://docs.swmansion.com/react-native-gesture-handler/

Check out our dedicated documentation page for info about this library, API reference and more: [https://docs.swmansion.com/react-native-gesture-handler/docs/](https://docs.swmansion.com/react-native-gesture-handler/docs/)

For Windows-specific documentation, check out the [Windows README](windows/RNGestureHandler/README.md).

## Examples

If you want to play with the API but don't feel like trying it on a real app, you can run the example project. Clone the repo, go to the `Example/` folder and run:
Expand All @@ -28,9 +30,9 @@ If you are running on ios, run `pod install` in the ios folder

Run `yarn start` to start the metro bundler

Run `react-native run-android` or `react-native run-ios` (depending on which platform you want to run the example app on).
Run `react-native run-android`, `react-native run-ios` or `react-native run-windows` (depending on which platform you want to run the example app on).

You will need to have an Android or iOS device or emulator connected as well as `react-native-cli` package installed globally.
You will need to have an Android / iOS / Windows device or emulator connected as well as `react-native-cli` package installed globally.

## React native Support

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"react-native": "^0.63.4",
"react-native-builder-bob": "^0.17.1",
"react-native-web": "^0.11.7",
"react-native-windows": "^0.63.0-0",
"react-test-renderer": "16.8.6",
"release-it": "^13.6.5",
"typescript": "^4.1.2"
Expand Down
92 changes: 92 additions & 0 deletions windows/RNGestureHandler/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
*AppPackages*
*BundleArtifacts*

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

#MonoDevelop
*.pidb
*.userprefs

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*
*.sass-cache

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

# vim Temp Files
*~

#NuGet
packages/
*.nupkg

#ncrunch
*ncrunch*
*crunch*.local.xml

# visual studio database projects
*.dbmdl

#Test files
*.testsettings

#Other files
*.DotSettings
.vs/
*project.lock.json

#Files generated by the VS build
**/Generated Files/**

25 changes: 25 additions & 0 deletions windows/RNGestureHandler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# react-native-gesture-handler Windows Implementation

## Module Installation
You can either use autolinking on react-native-windows 0.63 and later or manually link the module on earlier releases.

## Automatic install with autolinking on RNW >= 0.63
RNGestureHandler supports autolinking. Just call: `npm i react-native-gesture-handler --save`

## Manual installation on RNW >= 0.62
1. `npm install react-native-gesture-handler --save`
2. Open your solution in Visual Studio 2019 (eg. `windows\yourapp.sln`)
3. Right-click Solution icon in Solution Explorer > Add > Existing Project...
4. Add `node_modules\react-native-gesture-handler\windows\RNGestureHandler\RNGestureHandler.vcxproj`
5. Right-click main application project > Add > Reference...
6. Select `RNGestureHandler` in Solution Projects
7. In app `pch.h` add `#include "winrt/RNGestureHandler.h"`
8. In `App.cpp` add `PackageProviders().Append(winrt::RNGestureHandler::ReactPackageProvider());` before `InitializeComponent();`

## Module development

If you want to contribute to this module Windows implementation, first you must install the [Windows Development Dependencies](https://aka.ms/rnw-deps).

You must temporarily install the `react-native-windows` package. Versions of `react-native-windows` and `react-native` must match, e.g. if the module uses `[email protected]`, install `npm i react-native-windows@^0.62 --dev`.

Now, you will be able to open corresponding `RNGestureHandler.sln` file, e.g. `RNGestureHandler62.sln` for `[email protected]`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "pch.h"
#include "RNFlingHandler.h"

using namespace winrt::RNGestureHandler;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Input;

void RNFlingGestureHandler::sendFlingEvent(winrt::Windows::Foundation::Point pos)
{
RNGestureHandlerEventExtraData eventData;

eventData.hasXY = true;
eventData.x = pos.X;
eventData.y = pos.Y;

eventData.hasAbsoluteXY = true;
eventData.absoluteX = pos.X;
eventData.absoluteY = pos.Y;

RNGestureHandlerEvent event{};
event.viewTag = viewTag;
event.handlerTag = handlerTag;
event.state = RNGestureHandlerState::Active;
event.prevState = lastState;
event.extraData = &eventData;

sendEventsInState(RNGestureHandlerState::Active, &eventData);
sendTouchEvent(&event);
}

void RNFlingGestureHandler::onManipulationUpdated(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::ManipulationUpdatedEventArgs const& e)
{
sendFlingEvent(e.Position());
}

void RNFlingGestureHandler::onCrossSliding(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::CrossSlidingEventArgs const& e)
{
VERBOSE_DEBUG("onCrossSliding\n");
switch (e.CrossSlidingState())
{
case CrossSlidingState::Completed:
sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
break;
default:
sendFlingEvent(e.Position());
break;
}
}

void RNFlingGestureHandler::onDragging(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::DraggingEventArgs const& e)
{
VERBOSE_DEBUG("onDragging\n");
switch (e.DraggingState())
{
case DraggingState::Completed:
sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
break;
default:
sendFlingEvent(e.Position());
break;
}
}

void RNFlingGestureHandler::onManipulationCompleted(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::ManipulationCompletedEventArgs const&)
{
sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
}

void RNFlingGestureHandler::onPointerReleased(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
RNGestureHandler::onPointerReleased(sender, e);

sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "../RNGestureHandler.h"

namespace winrt::RNGestureHandler
{
struct RNFlingGestureHandler : RNGestureHandler
{
void onManipulationUpdated(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::ManipulationUpdatedEventArgs const& e) override;

void onManipulationCompleted(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::ManipulationCompletedEventArgs const& e) override;

void onPointerReleased(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e) override;

void onCrossSliding(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::CrossSlidingEventArgs const& e) override;

void onDragging(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::DraggingEventArgs const& e) override;

void sendFlingEvent(winrt::Windows::Foundation::Point point);
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "pch.h"
#include "RNForceTouchHandler.h"

using namespace winrt::RNGestureHandler;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Input;

void RNForceTouchGestureHandler::onManipulationUpdated(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::ManipulationUpdatedEventArgs const&)
{
// Not available under UWP.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include "../RNGestureHandler.h"

namespace winrt::RNGestureHandler
{
struct RNForceTouchGestureHandler : RNGestureHandler
{
void onManipulationUpdated(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::ManipulationUpdatedEventArgs const& e) override;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "pch.h"
#include "RNLongPressHandler.h"

using namespace winrt::RNGestureHandler;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Input;

void RNLongPressGestureHandler::onHolding(winrt::Windows::Foundation::IInspectable const&,
HoldingEventArgs const& e)
{
VERBOSE_DEBUG("onHolding\n");

RNGestureHandlerEventExtraData eventData;

eventData.hasXY = true;
eventData.x = e.Position().X;
eventData.y = e.Position().Y;

eventData.hasAbsoluteXY = true;
eventData.absoluteX = e.Position().X;
eventData.absoluteY = e.Position().Y;

sendEventsInState(RNGestureHandlerState::Active, &eventData);
}

void RNLongPressGestureHandler::onPointerReleased(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e)
{
RNGestureHandler::onPointerReleased(sender, e);

sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "../RNGestureHandler.h"

namespace winrt::RNGestureHandler
{
struct RNLongPressGestureHandler : RNGestureHandler
{
void onHolding(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Input::HoldingEventArgs const& e) override;

void onPointerReleased(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e) override;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "pch.h"
#include "RNPanHandler.h"

using namespace winrt::RNGestureHandler;
using namespace winrt::Windows::UI::Input;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Input;

void RNPanGestureHandler::onManipulationUpdated(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::ManipulationUpdatedEventArgs const& e)
{
RNGestureHandlerEventExtraData eventData;

eventData.hasTranslationXY = true;
eventData.translationX = e.Cumulative().Translation.X;
eventData.translationY = e.Cumulative().Translation.Y;

eventData.hasVelocityXY = true;
eventData.velocityX = e.Velocities().Linear.X;
eventData.velocityY = e.Velocities().Linear.Y;

eventData.hasXY = true;
eventData.x = e.Position().X;
eventData.y = e.Position().Y;

eventData.hasAbsoluteXY = true;
eventData.absoluteX = e.Position().X;
eventData.absoluteY = e.Position().Y;

RNGestureHandlerEvent event{};
event.viewTag = viewTag;
event.handlerTag = handlerTag;
event.state = RNGestureHandlerState::Active;
event.prevState = lastState;
event.extraData = &eventData;

sendEventsInState(RNGestureHandlerState::Active, &eventData);
sendTouchEvent(&event);
}

void RNPanGestureHandler::onManipulationCompleted(winrt::Windows::Foundation::IInspectable const&,
winrt::Windows::UI::Input::ManipulationCompletedEventArgs const&)
{
sendEventsInState(RNGestureHandlerState::End, 0);
sendEventsInState(RNGestureHandlerState::Undetermined, 0);
}
Loading