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

Fabric view props & events #2364

Open
wants to merge 1 commit into
base: meta/pristine
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once

#include <react/renderer/components/view/BaseTouch.h>

namespace facebook::react {

class HostPlatformTouch : public BaseTouch {
public:
/*
* The button indicating which pointer is used.
*/
int button;

/*
* The pointer type indicating the device type (e.g., mouse, pen, touch)
*/
std::string pointerType;

/*
* A flag indicating if the alt key is pressed.
*/
bool altKey;

/*
* A flag indicating if the control key is pressed.
*/
bool ctrlKey;

/*
* A flag indicating if the shift key is pressed.
*/
bool shiftKey;

/*
* A flag indicating if the shift key is pressed.
*/
bool metaKey;

/*
* Windows-specific timestamp field. We can't use the shared BaseTouch
* timestamp field beacuse it's a float and lacks sufficient resolution.
*/
double pointerTimestamp;
};

inline static void setTouchPayloadOnObject(
jsi::Object& object,
jsi::Runtime& runtime,
const HostPlatformTouch& touch) {
object.setProperty(runtime, "locationX", touch.offsetPoint.x);
object.setProperty(runtime, "locationY", touch.offsetPoint.y);
object.setProperty(runtime, "pageX", touch.pagePoint.x);
object.setProperty(runtime, "pageY", touch.pagePoint.y);
object.setProperty(runtime, "screenX", touch.screenPoint.x);
object.setProperty(runtime, "screenY", touch.screenPoint.y);
object.setProperty(runtime, "identifier", touch.identifier);
object.setProperty(runtime, "target", touch.target);
object.setProperty(runtime, "timestamp", touch.pointerTimestamp);
object.setProperty(runtime, "force", touch.force);
object.setProperty(runtime, "button", touch.button);
object.setProperty(runtime, "altKey", touch.altKey);
object.setProperty(runtime, "ctrlKey", touch.ctrlKey);
object.setProperty(runtime, "shiftKey", touch.shiftKey);
object.setProperty(runtime, "metaKey", touch.metaKey);
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "HostPlatformViewEventEmitter.h"

namespace facebook::react {

#pragma mark - Keyboard Events

static jsi::Value keyEventPayload(
jsi::Runtime& runtime,
const KeyEvent& event) {
auto payload = jsi::Object(runtime);
payload.setProperty(
runtime, "key", jsi::String::createFromUtf8(runtime, event.key));
payload.setProperty(runtime, "ctrlKey", event.ctrlKey);
payload.setProperty(runtime, "shiftKey", event.shiftKey);
payload.setProperty(runtime, "altKey", event.altKey);
payload.setProperty(runtime, "metaKey", event.metaKey);
payload.setProperty(runtime, "capsLockKey", event.capsLockKey);
payload.setProperty(runtime, "numericPadKey", event.numericPadKey);
payload.setProperty(runtime, "helpKey", event.helpKey);
payload.setProperty(runtime, "functionKey", event.functionKey);
return payload;
};

void HostPlatformViewEventEmitter::onKeyDown(const KeyEvent& keyEvent) const {
dispatchEvent("keyDown", [keyEvent](jsi::Runtime& runtime) {
return keyEventPayload(runtime, keyEvent);
});
}

void HostPlatformViewEventEmitter::onKeyUp(const KeyEvent& keyEvent) const {
dispatchEvent("keyUp", [keyEvent](jsi::Runtime& runtime) {
return keyEventPayload(runtime, keyEvent);
});
}

#pragma mark - Mouse Events

static jsi::Object mouseEventPayload(
jsi::Runtime& runtime,
const MouseEvent& event) {
auto payload = jsi::Object(runtime);
payload.setProperty(runtime, "clientX", event.clientX);
payload.setProperty(runtime, "clientY", event.clientY);
payload.setProperty(runtime, "screenX", event.screenX);
payload.setProperty(runtime, "screenY", event.screenY);
payload.setProperty(runtime, "altKey", event.altKey);
payload.setProperty(runtime, "ctrlKey", event.ctrlKey);
payload.setProperty(runtime, "shiftKey", event.shiftKey);
payload.setProperty(runtime, "metaKey", event.metaKey);
return payload;
};

void HostPlatformViewEventEmitter::onMouseEnter(
const MouseEvent& mouseEvent) const {
dispatchEvent("mouseEnter", [mouseEvent](jsi::Runtime& runtime) {
return mouseEventPayload(runtime, mouseEvent);
});
}

void HostPlatformViewEventEmitter::onMouseLeave(
const MouseEvent& mouseEvent) const {
dispatchEvent("mouseLeave", [mouseEvent](jsi::Runtime& runtime) {
return mouseEventPayload(runtime, mouseEvent);
});
}

void HostPlatformViewEventEmitter::onDoubleClick(
const MouseEvent& mouseEvent) const {
dispatchEvent("doubleClick", [mouseEvent](jsi::Runtime& runtime) {
return mouseEventPayload(runtime, mouseEvent);
});
}

#pragma mark - Drag and Drop Events

static jsi::Value dataTransferPayload(
jsi::Runtime& runtime,
const std::vector<DataTransferItem>& dataTransferItems) {
auto filesArray = jsi::Array(runtime, dataTransferItems.size());
auto itemsArray = jsi::Array(runtime, dataTransferItems.size());
auto typesArray = jsi::Array(runtime, dataTransferItems.size());
int i = 0;
for (const auto& transferItem : dataTransferItems) {
auto fileObject = jsi::Object(runtime);
fileObject.setProperty(runtime, "name", transferItem.name);
fileObject.setProperty(runtime, "type", transferItem.type);
fileObject.setProperty(runtime, "uri", transferItem.uri);
if (transferItem.size.has_value()) {
fileObject.setProperty(runtime, "size", *transferItem.size);
}
if (transferItem.width.has_value()) {
fileObject.setProperty(runtime, "width", *transferItem.width);
}
if (transferItem.height.has_value()) {
fileObject.setProperty(runtime, "height", *transferItem.height);
}
filesArray.setValueAtIndex(runtime, i, fileObject);

auto itemObject = jsi::Object(runtime);
itemObject.setProperty(runtime, "kind", transferItem.kind);
itemObject.setProperty(runtime, "type", transferItem.type);
itemsArray.setValueAtIndex(runtime, i, itemObject);

typesArray.setValueAtIndex(runtime, i, transferItem.type);
i++;
}

auto dataTransferObject = jsi::Object(runtime);
dataTransferObject.setProperty(runtime, "files", filesArray);
dataTransferObject.setProperty(runtime, "items", itemsArray);
dataTransferObject.setProperty(runtime, "types", typesArray);

return dataTransferObject;
}

static jsi::Value dragEventPayload(
jsi::Runtime& runtime,
const DragEvent& event) {
auto payload = mouseEventPayload(runtime, event);
auto dataTransferObject =
dataTransferPayload(runtime, event.dataTransferItems);
payload.setProperty(runtime, "dataTransfer", dataTransferObject);
return payload;
}

void HostPlatformViewEventEmitter::onDragEnter(
const DragEvent& dragEvent) const {
dispatchEvent("dragEnter", [dragEvent](jsi::Runtime& runtime) {
return dragEventPayload(runtime, dragEvent);
});
}

void HostPlatformViewEventEmitter::onDragLeave(
const DragEvent& dragEvent) const {
dispatchEvent("dragLeave", [dragEvent](jsi::Runtime& runtime) {
return dragEventPayload(runtime, dragEvent);
});
}

void HostPlatformViewEventEmitter::onDrop(const DragEvent& dragEvent) const {
dispatchEvent("drop", [dragEvent](jsi::Runtime& runtime) {
return dragEventPayload(runtime, dragEvent);
});
}

#pragma mark - Focus Events

void HostPlatformViewEventEmitter::onFocus() const {
dispatchEvent("focus");
}

void HostPlatformViewEventEmitter::onBlur() const {
dispatchEvent("blur");
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <react/renderer/components/view/BaseViewEventEmitter.h>
#include "KeyEvent.h"
#include "MouseEvent.h"

namespace facebook::react {

class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
public:
using BaseViewEventEmitter::BaseViewEventEmitter;

#pragma mark - Keyboard Events

void onKeyDown(const KeyEvent& keyEvent) const;
void onKeyUp(const KeyEvent& keyEvent) const;

#pragma mark - Mouse Events

void onMouseEnter(const MouseEvent& mouseEvent) const;
void onMouseLeave(const MouseEvent& mouseEvent) const;
void onDoubleClick(const MouseEvent& mouseEvent) const;

#pragma mark - Drag and Drop Events

void onDragEnter(const DragEvent& dragEvent) const;
void onDragLeave(const DragEvent& dragEvent) const;
void onDrop(const DragEvent& dragEvent) const;

#pragma mark - Focus Events

void onFocus() const;
void onBlur() const;
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
#include <array>
#include <bitset>
#include <cmath>
#include <optional>

namespace facebook::react {

struct HostPlatformViewEvents {
std::bitset<32> bits{};

enum class Offset : std::size_t {
// Keyboard Events
KeyDown = 1,
KeyUp = 2,

// Mouse Events
MouseEnter = 3,
MouseLeave = 4,
DoubleClick = 5,
};

constexpr bool operator[](const Offset offset) const {
return bits[static_cast<std::size_t>(offset)];
}

std::bitset<32>::reference operator[](const Offset offset) {
return bits[static_cast<std::size_t>(offset)];
}
};

inline static bool operator==(
const HostPlatformViewEvents& lhs,
const HostPlatformViewEvents& rhs) {
return lhs.bits == rhs.bits;
}

inline static bool operator!=(
const HostPlatformViewEvents& lhs,
const HostPlatformViewEvents& rhs) {
return lhs.bits != rhs.bits;
}

static inline HostPlatformViewEvents convertRawProp(
const PropsParserContext& context,
const RawProps& rawProps,
const HostPlatformViewEvents& sourceValue,
const HostPlatformViewEvents& defaultValue) {
HostPlatformViewEvents result{};
using Offset = HostPlatformViewEvents::Offset;

result[Offset::KeyDown] = convertRawProp(
context,
rawProps,
"onKeyDown",
sourceValue[Offset::KeyDown],
defaultValue[Offset::KeyDown]);
result[Offset::KeyUp] = convertRawProp(
context,
rawProps,
"onKeyUp",
sourceValue[Offset::KeyUp],
defaultValue[Offset::KeyUp]);

result[Offset::MouseEnter] = convertRawProp(
context,
rawProps,
"onMouseEnter",
sourceValue[Offset::MouseEnter],
defaultValue[Offset::MouseEnter]);
result[Offset::MouseLeave] = convertRawProp(
context,
rawProps,
"onMouseLeave",
sourceValue[Offset::MouseLeave],
defaultValue[Offset::MouseLeave]);

result[Offset::DoubleClick] = convertRawProp(
context,
rawProps,
"onDoubleClick",
sourceValue[Offset::DoubleClick],
defaultValue[Offset::DoubleClick]);

return result;
}

} // namespace facebook::react
Loading