yeet
This commit is contained in:
519
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp
generated
vendored
Normal file
519
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp
generated
vendored
Normal file
@ -0,0 +1,519 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "YogaLayoutableShadowNode.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include <react/components/view/ViewProps.h>
|
||||
#include <react/components/view/conversions.h>
|
||||
#include <react/core/LayoutConstraints.h>
|
||||
#include <react/core/LayoutContext.h>
|
||||
#include <react/debug/DebugStringConvertibleItem.h>
|
||||
#include <react/debug/SystraceSection.h>
|
||||
#include <yoga/Yoga.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static void applyLayoutConstraints(
|
||||
YGStyle &yogaStyle,
|
||||
LayoutConstraints const &layoutConstraints) {
|
||||
yogaStyle.minDimensions()[YGDimensionWidth] =
|
||||
yogaStyleValueFromFloat(layoutConstraints.minimumSize.width);
|
||||
yogaStyle.minDimensions()[YGDimensionHeight] =
|
||||
yogaStyleValueFromFloat(layoutConstraints.minimumSize.height);
|
||||
|
||||
yogaStyle.maxDimensions()[YGDimensionWidth] =
|
||||
yogaStyleValueFromFloat(layoutConstraints.maximumSize.width);
|
||||
yogaStyle.maxDimensions()[YGDimensionHeight] =
|
||||
yogaStyleValueFromFloat(layoutConstraints.maximumSize.height);
|
||||
|
||||
yogaStyle.direction() =
|
||||
yogaDirectionFromLayoutDirection(layoutConstraints.layoutDirection);
|
||||
}
|
||||
|
||||
ShadowNodeTraits YogaLayoutableShadowNode::BaseTraits() {
|
||||
auto traits = LayoutableShadowNode::BaseTraits();
|
||||
traits.set(ShadowNodeTraits::Trait::YogaLayoutableKind);
|
||||
return traits;
|
||||
}
|
||||
|
||||
YogaLayoutableShadowNode::YogaLayoutableShadowNode(
|
||||
ShadowNodeFragment const &fragment,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
ShadowNodeTraits traits)
|
||||
: LayoutableShadowNode(fragment, family, traits),
|
||||
yogaConfig_(nullptr),
|
||||
yogaNode_(&initializeYogaConfig(yogaConfig_)) {
|
||||
yogaNode_.setContext(this);
|
||||
|
||||
updateYogaProps();
|
||||
updateYogaChildren();
|
||||
}
|
||||
|
||||
YogaLayoutableShadowNode::YogaLayoutableShadowNode(
|
||||
ShadowNode const &sourceShadowNode,
|
||||
ShadowNodeFragment const &fragment)
|
||||
: LayoutableShadowNode(sourceShadowNode, fragment),
|
||||
yogaConfig_(nullptr),
|
||||
yogaNode_(
|
||||
static_cast<YogaLayoutableShadowNode const &>(sourceShadowNode)
|
||||
.yogaNode_,
|
||||
&initializeYogaConfig(yogaConfig_)) {
|
||||
yogaNode_.setContext(this);
|
||||
yogaNode_.setOwner(nullptr);
|
||||
|
||||
// Yoga node must inherit dirty flag.
|
||||
assert(
|
||||
static_cast<YogaLayoutableShadowNode const &>(sourceShadowNode)
|
||||
.yogaNode_.isDirty() == yogaNode_.isDirty());
|
||||
|
||||
if (fragment.props) {
|
||||
updateYogaProps();
|
||||
}
|
||||
|
||||
if (fragment.children) {
|
||||
updateYogaChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::cleanLayout() {
|
||||
yogaNode_.setDirty(false);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::dirtyLayout() {
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
bool YogaLayoutableShadowNode::getIsLayoutClean() const {
|
||||
return !yogaNode_.isDirty();
|
||||
}
|
||||
|
||||
bool YogaLayoutableShadowNode::getHasNewLayout() const {
|
||||
return yogaNode_.getHasNewLayout();
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::setHasNewLayout(bool hasNewLayout) {
|
||||
yogaNode_.setHasNewLayout(hasNewLayout);
|
||||
}
|
||||
|
||||
#pragma mark - Mutating Methods
|
||||
|
||||
void YogaLayoutableShadowNode::enableMeasurement() {
|
||||
ensureUnsealed();
|
||||
|
||||
yogaNode_.setMeasureFunc(
|
||||
YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::appendChild(ShadowNode::Shared const &child) {
|
||||
ensureUnsealed();
|
||||
|
||||
LayoutableShadowNode::appendChild(child);
|
||||
|
||||
auto yogaLayoutableChild =
|
||||
traitCast<YogaLayoutableShadowNode const *>(child.get());
|
||||
if (yogaLayoutableChild) {
|
||||
appendChildYogaNode(*yogaLayoutableChild);
|
||||
}
|
||||
}
|
||||
|
||||
bool YogaLayoutableShadowNode::doesOwn(
|
||||
YogaLayoutableShadowNode const &child) const {
|
||||
return child.yogaNode_.getOwner() == &yogaNode_;
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::appendChildYogaNode(
|
||||
YogaLayoutableShadowNode const &child) {
|
||||
ensureUnsealed();
|
||||
|
||||
if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) {
|
||||
// This node is a declared leaf, therefore we must not add the Yoga node as
|
||||
// a child.
|
||||
return;
|
||||
}
|
||||
|
||||
yogaNode_.setDirty(true);
|
||||
|
||||
auto yogaNodeRawPtr = &yogaNode_;
|
||||
auto childYogaNodeRawPtr = &child.yogaNode_;
|
||||
auto childNodePtr = const_cast<YogaLayoutableShadowNode *>(&child);
|
||||
|
||||
if (childYogaNodeRawPtr->getOwner() != nullptr) {
|
||||
childNodePtr =
|
||||
&cloneAndReplaceChild(*childNodePtr, yogaNode_.getChildren().size());
|
||||
childYogaNodeRawPtr = &childNodePtr->yogaNode_;
|
||||
}
|
||||
|
||||
// Inserted node must have a clear owner (must not be shared).
|
||||
assert(childYogaNodeRawPtr->getOwner() == nullptr);
|
||||
|
||||
childNodePtr->ensureUnsealed();
|
||||
childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);
|
||||
|
||||
yogaNodeRawPtr->insertChild(
|
||||
childYogaNodeRawPtr, yogaNodeRawPtr->getChildren().size());
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::updateYogaChildren() {
|
||||
if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ensureUnsealed();
|
||||
|
||||
auto &children = getChildren();
|
||||
|
||||
// Optimization:
|
||||
// If the new list of child nodes consists of clean nodes, and if their styles
|
||||
// are identical to styles of old children, we don't dirty the node.
|
||||
bool isClean = !yogaNode_.getDirtied() &&
|
||||
children.size() == yogaNode_.getChildren().size();
|
||||
auto oldChildren = isClean ? yogaNode_.getChildren() : YGVector{};
|
||||
|
||||
yogaNode_.setChildren({});
|
||||
|
||||
auto i = int{0};
|
||||
for (auto const &child : children) {
|
||||
auto yogaLayoutableChild =
|
||||
traitCast<YogaLayoutableShadowNode const *>(child.get());
|
||||
|
||||
if (!yogaLayoutableChild) {
|
||||
continue;
|
||||
}
|
||||
|
||||
appendChildYogaNode(*yogaLayoutableChild);
|
||||
|
||||
isClean = isClean && !yogaLayoutableChild->yogaNode_.isDirty() &&
|
||||
yogaLayoutableChild->yogaNode_.getStyle() ==
|
||||
oldChildren[i++]->getStyle();
|
||||
}
|
||||
|
||||
yogaNode_.setDirty(!isClean);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::updateYogaProps() {
|
||||
ensureUnsealed();
|
||||
|
||||
auto props = static_cast<YogaStylableProps const &>(*props_);
|
||||
|
||||
// Resetting `dirty` flag only if `yogaStyle` portion of `Props` was changed.
|
||||
if (!yogaNode_.isDirty() && (props.yogaStyle != yogaNode_.getStyle())) {
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
yogaNode_.setStyle(props.yogaStyle);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::setSize(Size size) const {
|
||||
ensureUnsealed();
|
||||
|
||||
auto style = yogaNode_.getStyle();
|
||||
style.dimensions()[YGDimensionWidth] = yogaStyleValueFromFloat(size.width);
|
||||
style.dimensions()[YGDimensionHeight] = yogaStyleValueFromFloat(size.height);
|
||||
yogaNode_.setStyle(style);
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::setPadding(RectangleEdges<Float> padding) const {
|
||||
ensureUnsealed();
|
||||
|
||||
auto style = yogaNode_.getStyle();
|
||||
style.padding()[YGEdgeTop] = yogaStyleValueFromFloat(padding.top);
|
||||
style.padding()[YGEdgeLeft] = yogaStyleValueFromFloat(padding.left);
|
||||
style.padding()[YGEdgeRight] = yogaStyleValueFromFloat(padding.right);
|
||||
style.padding()[YGEdgeBottom] = yogaStyleValueFromFloat(padding.bottom);
|
||||
yogaNode_.setStyle(style);
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::setPositionType(
|
||||
YGPositionType positionType) const {
|
||||
ensureUnsealed();
|
||||
|
||||
auto style = yogaNode_.getStyle();
|
||||
style.positionType() = positionType;
|
||||
yogaNode_.setStyle(style);
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::layoutTree(
|
||||
LayoutContext layoutContext,
|
||||
LayoutConstraints layoutConstraints) {
|
||||
ensureUnsealed();
|
||||
|
||||
/*
|
||||
* In Yoga, every single Yoga Node has to have a (non-null) pointer to
|
||||
* Yoga Config (this config can be shared between many nodes),
|
||||
* so every node can be individually configured. This does *not* mean
|
||||
* however that Yoga consults with every single Yoga Node Config for every
|
||||
* config parameter. Especially in case of `pointScaleFactor`,
|
||||
* the only value in the config of the root node is taken into account
|
||||
* (and this is by design).
|
||||
*/
|
||||
yogaConfig_.pointScaleFactor = layoutContext.pointScaleFactor;
|
||||
|
||||
applyLayoutConstraints(yogaNode_.getStyle(), layoutConstraints);
|
||||
|
||||
if (layoutContext.swapLeftAndRightInRTL) {
|
||||
swapLeftAndRightInTree(*this);
|
||||
}
|
||||
|
||||
{
|
||||
SystraceSection s("YogaLayoutableShadowNode::YGNodeCalculateLayout");
|
||||
|
||||
YGNodeCalculateLayout(
|
||||
&yogaNode_, YGUndefined, YGUndefined, YGDirectionInherit);
|
||||
}
|
||||
|
||||
if (getHasNewLayout()) {
|
||||
auto layoutMetrics = layoutMetricsFromYogaNode(yogaNode_);
|
||||
layoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor;
|
||||
setLayoutMetrics(layoutMetrics);
|
||||
setHasNewLayout(false);
|
||||
}
|
||||
|
||||
layout(layoutContext);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::layoutChildren(LayoutContext layoutContext) {
|
||||
assert(!yogaNode_.isDirty());
|
||||
|
||||
for (const auto &childYogaNode : yogaNode_.getChildren()) {
|
||||
if (!childYogaNode->getHasNewLayout()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(!childYogaNode->isDirty());
|
||||
|
||||
auto childNode =
|
||||
static_cast<YogaLayoutableShadowNode *>(childYogaNode->getContext());
|
||||
|
||||
// Verifying that the Yoga node belongs to the ShadowNode.
|
||||
assert(&childNode->yogaNode_ == childYogaNode);
|
||||
|
||||
LayoutMetrics childLayoutMetrics =
|
||||
layoutMetricsFromYogaNode(childNode->yogaNode_);
|
||||
childLayoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor;
|
||||
|
||||
// We must copy layout metrics from Yoga node only once (when the parent
|
||||
// node exclusively ownes the child node).
|
||||
assert(childYogaNode->getOwner() == &yogaNode_);
|
||||
|
||||
childNode->ensureUnsealed();
|
||||
auto affected = childNode->setLayoutMetrics(childLayoutMetrics);
|
||||
|
||||
if (affected && layoutContext.affectedNodes) {
|
||||
layoutContext.affectedNodes->push_back(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YogaLayoutableShadowNode &YogaLayoutableShadowNode::cloneAndReplaceChild(
|
||||
YogaLayoutableShadowNode &child,
|
||||
int suggestedIndex) {
|
||||
auto clonedChildShadowNode = child.clone({});
|
||||
replaceChild(child, clonedChildShadowNode, suggestedIndex);
|
||||
|
||||
return static_cast<YogaLayoutableShadowNode &>(*clonedChildShadowNode);
|
||||
}
|
||||
|
||||
#pragma mark - Yoga Connectors
|
||||
|
||||
YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(
|
||||
YGNode *oldYogaNode,
|
||||
YGNode *parentYogaNode,
|
||||
int childIndex) {
|
||||
SystraceSection s("YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector");
|
||||
|
||||
// At this point it is guaranteed that all shadow nodes associated with yoga
|
||||
// nodes are `YogaLayoutableShadowNode` subclasses.
|
||||
auto parentNode =
|
||||
static_cast<YogaLayoutableShadowNode *>(parentYogaNode->getContext());
|
||||
auto oldNode =
|
||||
static_cast<YogaLayoutableShadowNode *>(oldYogaNode->getContext());
|
||||
auto clonedNode = &parentNode->cloneAndReplaceChild(*oldNode, childIndex);
|
||||
return &clonedNode->yogaNode_;
|
||||
}
|
||||
|
||||
YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(
|
||||
YGNode *yogaNode,
|
||||
float width,
|
||||
YGMeasureMode widthMode,
|
||||
float height,
|
||||
YGMeasureMode heightMode) {
|
||||
SystraceSection s(
|
||||
"YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector");
|
||||
|
||||
auto shadowNodeRawPtr =
|
||||
static_cast<YogaLayoutableShadowNode *>(yogaNode->getContext());
|
||||
|
||||
auto minimumSize = Size{0, 0};
|
||||
auto maximumSize = Size{std::numeric_limits<Float>::infinity(),
|
||||
std::numeric_limits<Float>::infinity()};
|
||||
|
||||
switch (widthMode) {
|
||||
case YGMeasureModeUndefined:
|
||||
break;
|
||||
case YGMeasureModeExactly:
|
||||
minimumSize.width = floatFromYogaFloat(width);
|
||||
maximumSize.width = floatFromYogaFloat(width);
|
||||
break;
|
||||
case YGMeasureModeAtMost:
|
||||
maximumSize.width = floatFromYogaFloat(width);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (heightMode) {
|
||||
case YGMeasureModeUndefined:
|
||||
break;
|
||||
case YGMeasureModeExactly:
|
||||
minimumSize.height = floatFromYogaFloat(height);
|
||||
maximumSize.height = floatFromYogaFloat(height);
|
||||
break;
|
||||
case YGMeasureModeAtMost:
|
||||
maximumSize.height = floatFromYogaFloat(height);
|
||||
break;
|
||||
}
|
||||
|
||||
auto size = shadowNodeRawPtr->measure({minimumSize, maximumSize});
|
||||
|
||||
return YGSize{yogaFloatFromFloat(size.width),
|
||||
yogaFloatFromFloat(size.height)};
|
||||
}
|
||||
|
||||
YGConfig &YogaLayoutableShadowNode::initializeYogaConfig(YGConfig &config) {
|
||||
config.setCloneNodeCallback(
|
||||
YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector);
|
||||
config.useLegacyStretchBehaviour = true;
|
||||
return config;
|
||||
}
|
||||
|
||||
#pragma mark - RTL left and right swapping
|
||||
|
||||
void YogaLayoutableShadowNode::swapLeftAndRightInTree(
|
||||
YogaLayoutableShadowNode const &shadowNode) {
|
||||
swapLeftAndRightInYogaStyleProps(shadowNode);
|
||||
swapLeftAndRightInViewProps(shadowNode);
|
||||
|
||||
for (auto &child : shadowNode.getChildren()) {
|
||||
auto const yogaLayoutableChild =
|
||||
traitCast<YogaLayoutableShadowNode const *>(child.get());
|
||||
if (yogaLayoutableChild && !yogaLayoutableChild->doesOwn(shadowNode)) {
|
||||
swapLeftAndRightInTree(*yogaLayoutableChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::swapLeftAndRightInYogaStyleProps(
|
||||
YogaLayoutableShadowNode const &shadowNode) {
|
||||
auto yogaStyle = shadowNode.yogaNode_.getStyle();
|
||||
|
||||
YGStyle::Edges const &position = yogaStyle.position();
|
||||
YGStyle::Edges const &padding = yogaStyle.padding();
|
||||
YGStyle::Edges const &margin = yogaStyle.margin();
|
||||
|
||||
// Swap Yoga node values, position, padding and margin.
|
||||
|
||||
if (yogaStyle.position()[YGEdgeLeft] != YGValueUndefined) {
|
||||
yogaStyle.position()[YGEdgeStart] = position[YGEdgeLeft];
|
||||
yogaStyle.position()[YGEdgeLeft] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (yogaStyle.position()[YGEdgeRight] != YGValueUndefined) {
|
||||
yogaStyle.position()[YGEdgeEnd] = position[YGEdgeRight];
|
||||
yogaStyle.position()[YGEdgeRight] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (yogaStyle.padding()[YGEdgeLeft] != YGValueUndefined) {
|
||||
yogaStyle.padding()[YGEdgeStart] = padding[YGEdgeLeft];
|
||||
yogaStyle.padding()[YGEdgeLeft] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (yogaStyle.padding()[YGEdgeRight] != YGValueUndefined) {
|
||||
yogaStyle.padding()[YGEdgeEnd] = padding[YGEdgeRight];
|
||||
yogaStyle.padding()[YGEdgeRight] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (yogaStyle.margin()[YGEdgeLeft] != YGValueUndefined) {
|
||||
yogaStyle.margin()[YGEdgeStart] = margin[YGEdgeLeft];
|
||||
yogaStyle.margin()[YGEdgeLeft] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (yogaStyle.margin()[YGEdgeRight] != YGValueUndefined) {
|
||||
yogaStyle.margin()[YGEdgeEnd] = margin[YGEdgeRight];
|
||||
yogaStyle.margin()[YGEdgeLeft] = YGValueUndefined;
|
||||
}
|
||||
|
||||
shadowNode.yogaNode_.setStyle(yogaStyle);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::swapLeftAndRightInViewProps(
|
||||
YogaLayoutableShadowNode const &shadowNode) {
|
||||
auto &typedCasting = static_cast<ViewProps const &>(*shadowNode.props_);
|
||||
auto &props = const_cast<ViewProps &>(typedCasting);
|
||||
|
||||
// Swap border node values, borderRadii, borderColors and borderStyles.
|
||||
if (props.borderRadii.topLeft.hasValue()) {
|
||||
props.borderRadii.topStart = props.borderRadii.topLeft;
|
||||
props.borderRadii.topLeft.clear();
|
||||
}
|
||||
|
||||
if (props.borderRadii.bottomLeft.hasValue()) {
|
||||
props.borderRadii.bottomStart = props.borderRadii.bottomLeft;
|
||||
props.borderRadii.bottomLeft.clear();
|
||||
}
|
||||
|
||||
if (props.borderRadii.topRight.hasValue()) {
|
||||
props.borderRadii.topEnd = props.borderRadii.topRight;
|
||||
props.borderRadii.topRight.clear();
|
||||
}
|
||||
|
||||
if (props.borderRadii.bottomRight.hasValue()) {
|
||||
props.borderRadii.bottomEnd = props.borderRadii.bottomRight;
|
||||
props.borderRadii.bottomRight.clear();
|
||||
}
|
||||
|
||||
if (props.borderColors.left.hasValue()) {
|
||||
props.borderColors.start = props.borderColors.left;
|
||||
props.borderColors.left.clear();
|
||||
}
|
||||
|
||||
if (props.borderColors.right.hasValue()) {
|
||||
props.borderColors.end = props.borderColors.right;
|
||||
props.borderColors.right.clear();
|
||||
}
|
||||
|
||||
if (props.borderStyles.left.hasValue()) {
|
||||
props.borderStyles.start = props.borderStyles.left;
|
||||
props.borderStyles.left.clear();
|
||||
}
|
||||
|
||||
if (props.borderStyles.right.hasValue()) {
|
||||
props.borderStyles.end = props.borderStyles.right;
|
||||
props.borderStyles.right.clear();
|
||||
}
|
||||
|
||||
YGStyle::Edges const &border = props.yogaStyle.border();
|
||||
|
||||
if (props.yogaStyle.border()[YGEdgeLeft] != YGValueUndefined) {
|
||||
props.yogaStyle.border()[YGEdgeStart] = border[YGEdgeLeft];
|
||||
props.yogaStyle.border()[YGEdgeLeft] = YGValueUndefined;
|
||||
}
|
||||
|
||||
if (props.yogaStyle.border()[YGEdgeRight] != YGValueUndefined) {
|
||||
props.yogaStyle.border()[YGEdgeEnd] = border[YGEdgeRight];
|
||||
props.yogaStyle.border()[YGEdgeRight] = YGValueUndefined;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
196
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.h
generated
vendored
Normal file
196
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.h
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <yoga/YGNode.h>
|
||||
|
||||
#include <react/components/view/YogaStylableProps.h>
|
||||
#include <react/core/LayoutableShadowNode.h>
|
||||
#include <react/core/Sealable.h>
|
||||
#include <react/core/ShadowNode.h>
|
||||
#include <react/debug/DebugStringConvertible.h>
|
||||
#include <react/graphics/Geometry.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class YogaLayoutableShadowNode : public LayoutableShadowNode {
|
||||
public:
|
||||
using UnsharedList = better::small_vector<
|
||||
YogaLayoutableShadowNode *,
|
||||
kShadowNodeChildrenSmallVectorSize>;
|
||||
|
||||
static ShadowNodeTraits BaseTraits();
|
||||
|
||||
#pragma mark - Constructors
|
||||
|
||||
YogaLayoutableShadowNode(
|
||||
ShadowNodeFragment const &fragment,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
ShadowNodeTraits traits);
|
||||
|
||||
YogaLayoutableShadowNode(
|
||||
ShadowNode const &sourceShadowNode,
|
||||
ShadowNodeFragment const &fragment);
|
||||
|
||||
#pragma mark - Mutating Methods
|
||||
|
||||
/*
|
||||
* Connects `measureFunc` function of Yoga node with
|
||||
* `LayoutableShadowNode::measure()` method.
|
||||
*/
|
||||
void enableMeasurement();
|
||||
|
||||
void appendChild(ShadowNode::Shared const &child);
|
||||
|
||||
void updateYogaChildren();
|
||||
|
||||
void updateYogaProps();
|
||||
|
||||
/*
|
||||
* Sets layoutable size of node.
|
||||
*/
|
||||
void setSize(Size size) const;
|
||||
|
||||
void setPadding(RectangleEdges<Float> padding) const;
|
||||
|
||||
/*
|
||||
* Sets position type of Yoga node (relative, absolute).
|
||||
*/
|
||||
void setPositionType(YGPositionType positionType) const;
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
void cleanLayout() override;
|
||||
void dirtyLayout() override;
|
||||
bool getIsLayoutClean() const override;
|
||||
|
||||
void setHasNewLayout(bool hasNewLayout) override;
|
||||
bool getHasNewLayout() const override;
|
||||
|
||||
/*
|
||||
* Computes layout using Yoga layout engine.
|
||||
* See `LayoutableShadowNode` for more details.
|
||||
*/
|
||||
void layoutTree(
|
||||
LayoutContext layoutContext,
|
||||
LayoutConstraints layoutConstraints) override;
|
||||
|
||||
void layoutChildren(LayoutContext layoutContext) override;
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Yoga config associated (only) with this particular node.
|
||||
*/
|
||||
YGConfig yogaConfig_;
|
||||
|
||||
/*
|
||||
* All Yoga functions only accept non-const arguments, so we have to mark
|
||||
* Yoga node as `mutable` here to avoid `static_cast`ing the pointer to this
|
||||
* all the time.
|
||||
*/
|
||||
mutable YGNode yogaNode_;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Return true if child's yogaNode's owner is this->yogaNode_. Otherwise
|
||||
* returns false.
|
||||
*/
|
||||
bool doesOwn(YogaLayoutableShadowNode const &child) const;
|
||||
|
||||
/*
|
||||
* Appends `child`'s Yoga node to the own Yoga node.
|
||||
* Complements `ShadowNode::appendChild(...)` functionality from Yoga
|
||||
* perspective.
|
||||
*/
|
||||
void appendChildYogaNode(YogaLayoutableShadowNode const &child);
|
||||
|
||||
YogaLayoutableShadowNode &cloneAndReplaceChild(
|
||||
YogaLayoutableShadowNode &child,
|
||||
int suggestedIndex);
|
||||
|
||||
static YGConfig &initializeYogaConfig(YGConfig &config);
|
||||
static YGNode *yogaNodeCloneCallbackConnector(
|
||||
YGNode *oldYogaNode,
|
||||
YGNode *parentYogaNode,
|
||||
int childIndex);
|
||||
static YGSize yogaNodeMeasureCallbackConnector(
|
||||
YGNode *yogaNode,
|
||||
float width,
|
||||
YGMeasureMode widthMode,
|
||||
float height,
|
||||
YGMeasureMode heightMode);
|
||||
|
||||
/*
|
||||
* Walks though shadow node hierarchy and reassign following values:
|
||||
* - (left|right) → (start|end)
|
||||
* - margin(Left|Right) → margin(Start|End)
|
||||
* - padding(Left|Right) → padding(Start|End)
|
||||
* - borderTop(Left|Right)Radius → borderTop(Start|End)Radius
|
||||
* - borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
|
||||
* - border(Left|Right)Width → border(Start|End)Width
|
||||
* - border(Left|Right)Color → border(Start|End)Color
|
||||
* This is neccesarry to be backwards compatible with Paper, it swaps the
|
||||
* values as well in https://fburl.com/diffusion/kl7bjr3h
|
||||
*/
|
||||
static void swapLeftAndRightInTree(
|
||||
YogaLayoutableShadowNode const &shadowNode);
|
||||
/*
|
||||
* In shadow node passed as argument, reassigns following values
|
||||
* - borderTop(Left|Right)Radius → borderTop(Start|End)Radius
|
||||
* - borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
|
||||
* - border(Left|Right)Width → border(Start|End)Width
|
||||
* - border(Left|Right)Color → border(Start|End)Color
|
||||
*/
|
||||
static void swapLeftAndRightInViewProps(
|
||||
YogaLayoutableShadowNode const &shadowNode);
|
||||
/*
|
||||
* In yoga node passed as argument, reassigns following values
|
||||
* - (left|right) → (start|end)
|
||||
* - margin(Left|Right) → margin(Start|End)
|
||||
* - padding(Left|Right) → padding(Start|End)
|
||||
*/
|
||||
static void swapLeftAndRightInYogaStyleProps(
|
||||
YogaLayoutableShadowNode const &shadowNode);
|
||||
};
|
||||
|
||||
template <>
|
||||
inline YogaLayoutableShadowNode const &
|
||||
traitCast<YogaLayoutableShadowNode const &>(ShadowNode const &shadowNode) {
|
||||
bool castable =
|
||||
shadowNode.getTraits().check(ShadowNodeTraits::Trait::YogaLayoutableKind);
|
||||
assert(
|
||||
castable ==
|
||||
(dynamic_cast<YogaLayoutableShadowNode const *>(&shadowNode) != nullptr));
|
||||
assert(castable);
|
||||
(void)castable;
|
||||
return static_cast<YogaLayoutableShadowNode const &>(shadowNode);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline YogaLayoutableShadowNode const *
|
||||
traitCast<YogaLayoutableShadowNode const *>(ShadowNode const *shadowNode) {
|
||||
if (!shadowNode) {
|
||||
return nullptr;
|
||||
}
|
||||
bool castable = shadowNode->getTraits().check(
|
||||
ShadowNodeTraits::Trait::YogaLayoutableKind);
|
||||
assert(
|
||||
castable ==
|
||||
(dynamic_cast<YogaLayoutableShadowNode const *>(shadowNode) != nullptr));
|
||||
if (!castable) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<YogaLayoutableShadowNode const *>(shadowNode);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
97
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp
generated
vendored
Normal file
97
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "YogaStylableProps.h"
|
||||
|
||||
#include <react/components/view/conversions.h>
|
||||
#include <react/components/view/propsConversions.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
#include <react/debug/debugStringConvertibleUtils.h>
|
||||
#include <yoga/YGNode.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
#include "conversions.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
YogaStylableProps::YogaStylableProps(
|
||||
YogaStylableProps const &sourceProps,
|
||||
RawProps const &rawProps)
|
||||
: Props(sourceProps, rawProps),
|
||||
yogaStyle(convertRawProp(rawProps, sourceProps.yogaStyle)){};
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const {
|
||||
auto const defaultYogaStyle = YGStyle{};
|
||||
return {
|
||||
debugStringConvertibleItem(
|
||||
"direction", yogaStyle.direction(), defaultYogaStyle.direction()),
|
||||
debugStringConvertibleItem(
|
||||
"flexDirection",
|
||||
yogaStyle.flexDirection(),
|
||||
defaultYogaStyle.flexDirection()),
|
||||
debugStringConvertibleItem(
|
||||
"justifyContent",
|
||||
yogaStyle.justifyContent(),
|
||||
defaultYogaStyle.justifyContent()),
|
||||
debugStringConvertibleItem(
|
||||
"alignContent",
|
||||
yogaStyle.alignContent(),
|
||||
defaultYogaStyle.alignContent()),
|
||||
debugStringConvertibleItem(
|
||||
"alignItems", yogaStyle.alignItems(), defaultYogaStyle.alignItems()),
|
||||
debugStringConvertibleItem(
|
||||
"alignSelf", yogaStyle.alignSelf(), defaultYogaStyle.alignSelf()),
|
||||
debugStringConvertibleItem(
|
||||
"positionType",
|
||||
yogaStyle.positionType(),
|
||||
defaultYogaStyle.positionType()),
|
||||
debugStringConvertibleItem(
|
||||
"flexWrap", yogaStyle.flexWrap(), defaultYogaStyle.flexWrap()),
|
||||
debugStringConvertibleItem(
|
||||
"overflow", yogaStyle.overflow(), defaultYogaStyle.overflow()),
|
||||
debugStringConvertibleItem(
|
||||
"display", yogaStyle.display(), defaultYogaStyle.display()),
|
||||
debugStringConvertibleItem(
|
||||
"flex", yogaStyle.flex(), defaultYogaStyle.flex()),
|
||||
debugStringConvertibleItem(
|
||||
"flexGrow", yogaStyle.flexGrow(), defaultYogaStyle.flexGrow()),
|
||||
debugStringConvertibleItem(
|
||||
"flexShrink", yogaStyle.flexShrink(), defaultYogaStyle.flexShrink()),
|
||||
debugStringConvertibleItem(
|
||||
"flexBasis", yogaStyle.flexBasis(), defaultYogaStyle.flexBasis()),
|
||||
debugStringConvertibleItem(
|
||||
"margin", yogaStyle.margin(), defaultYogaStyle.margin()),
|
||||
debugStringConvertibleItem(
|
||||
"position", yogaStyle.position(), defaultYogaStyle.position()),
|
||||
debugStringConvertibleItem(
|
||||
"padding", yogaStyle.padding(), defaultYogaStyle.padding()),
|
||||
debugStringConvertibleItem(
|
||||
"border", yogaStyle.border(), defaultYogaStyle.border()),
|
||||
debugStringConvertibleItem(
|
||||
"dimensions", yogaStyle.dimensions(), defaultYogaStyle.dimensions()),
|
||||
debugStringConvertibleItem(
|
||||
"minDimensions",
|
||||
yogaStyle.minDimensions(),
|
||||
defaultYogaStyle.minDimensions()),
|
||||
debugStringConvertibleItem(
|
||||
"maxDimensions",
|
||||
yogaStyle.maxDimensions(),
|
||||
defaultYogaStyle.maxDimensions()),
|
||||
debugStringConvertibleItem(
|
||||
"aspectRatio",
|
||||
yogaStyle.aspectRatio(),
|
||||
defaultYogaStyle.aspectRatio()),
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
39
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h
generated
vendored
Normal file
39
node_modules/react-native/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 <yoga/YGStyle.h>
|
||||
|
||||
#include <react/core/Props.h>
|
||||
#include <react/debug/DebugStringConvertible.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class YogaStylableProps : public Props {
|
||||
public:
|
||||
YogaStylableProps() = default;
|
||||
YogaStylableProps(
|
||||
YogaStylableProps const &sourceProps,
|
||||
RawProps const &rawProps);
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
YGStyle yogaStyle{};
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
|
||||
#pragma mark - DebugStringConvertible (Partial)
|
||||
|
||||
SharedDebugStringConvertibleList getDebugProps() const;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Reference in New Issue
Block a user