Skip to content

Commit

Permalink
Fabric: New way (third attempt) to specify layout constraints for YGN…
Browse files Browse the repository at this point in the history
…odeCalculateLayout

Summary:
Surprisingly, it's not that trivial to pass `LayoutContrants` to `YGNodeCalculateLayout` in a way that always works. The problem is that `YGNodeCalculateLayout` does not allow expressing the constraints explicitly, so we need to pass them as `YGStyle` properties of a root node. With this approach, we unconditionally apply them as `YGStyle`s as actual values or `Undefined` value (which overrides some other values that can be previously set by calling this function or other code). We also intentionally preserve `height` and `width` values because it's a common use-case when a component explicitly specifies its size.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D26583550

fbshipit-source-id: 2cd506fbdc9e6a1a8f119d09ccfd34f876a13625
  • Loading branch information
shergin authored and facebook-github-bot committed Feb 22, 2021
1 parent abf079a commit 099e7aa
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -363,48 +363,33 @@ void YogaLayoutableShadowNode::layoutTree(
// implementation detail and are not defined in `CSS Flexible Box Layout
// Module`. Yoga C++ API (and `YGNodeCalculateLayout` function particularly)
// does not allow to specify the measure modes explicitly. Instead, it infers
// these from styles associated with the root node. The actual inferring logic
// is complex but it has a quite reasonable effect: to ensure applying proper
// layout restrictions we have to express constraints we have and avoid
// specifying anything that might trigger some unexpected side-effect. To do
// this, we clear all dimensional styles and apply only parts that we need to
// ensure.
// these from styles associated with the root node.
// To pass the actual layout constraints to Yoga we represent them as
// `(min/max)(Height/Width)` style properties. Also, we pass `ownerWidth` &
// `ownerHeight` to allow proper calculation of relative (e.g. specified in
// percents) style values.

auto &yogaStyle = yogaNode_.getStyle();

yogaStyle.minDimensions()[YGDimensionWidth] = YGValueUndefined;
yogaStyle.minDimensions()[YGDimensionHeight] = YGValueUndefined;
yogaStyle.maxDimensions()[YGDimensionWidth] = YGValueUndefined;
yogaStyle.maxDimensions()[YGDimensionHeight] = YGValueUndefined;
yogaStyle.dimensions()[YGDimensionWidth] = YGValueUndefined;
yogaStyle.dimensions()[YGDimensionHeight] = YGValueUndefined;
auto ownerWidth = yogaFloatFromFloat(maximumSize.width);
auto ownerHeight = yogaFloatFromFloat(maximumSize.height);

auto ownerWidth = YGUndefined;
auto ownerHeight = YGUndefined;
yogaStyle.maxDimensions()[YGDimensionWidth] = std::isfinite(maximumSize.width)
? yogaStyleValueFromFloat(maximumSize.width)
: YGValueUndefined;

if (!std::isinf(maximumSize.width)) {
yogaStyle.maxDimensions()[YGDimensionWidth] =
yogaStyleValueFromFloat(maximumSize.width);
yogaStyle.maxDimensions()[YGDimensionHeight] =
std::isfinite(maximumSize.height)
? yogaStyleValueFromFloat(maximumSize.height)
: YGValueUndefined;

ownerWidth = yogaFloatFromFloat(maximumSize.width);
}

if (!std::isinf(maximumSize.height)) {
yogaStyle.maxDimensions()[YGDimensionHeight] =
yogaStyleValueFromFloat(maximumSize.height);

ownerHeight = yogaFloatFromFloat(maximumSize.height);
}
yogaStyle.minDimensions()[YGDimensionWidth] = minimumSize.width > 0
? yogaStyleValueFromFloat(minimumSize.width)
: YGValueUndefined;

if (!std::isinf(minimumSize.width)) {
yogaStyle.minDimensions()[YGDimensionWidth] =
yogaStyleValueFromFloat(minimumSize.width);
}

if (!std::isinf(minimumSize.height)) {
yogaStyle.minDimensions()[YGDimensionHeight] =
yogaStyleValueFromFloat(minimumSize.height);
}
yogaStyle.minDimensions()[YGDimensionHeight] = minimumSize.height > 0
? yogaStyleValueFromFloat(minimumSize.height)
: YGValueUndefined;

auto direction =
yogaDirectionFromLayoutDirection(layoutConstraints.layoutDirection);
Expand Down
4 changes: 2 additions & 2 deletions ReactCommon/react/renderer/components/view/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ inline Float floatFromYogaFloat(float value) {
}

inline float yogaFloatFromFloat(Float value) {
if (std::isinf(value)) {
if (!std::isfinite(value)) {
return YGUndefined;
}

Expand Down Expand Up @@ -90,7 +90,7 @@ inline YGFloatOptional yogaOptionalFloatFromFloat(Float value) {
inline YGValue yogaStyleValueFromFloat(
const Float &value,
YGUnit unit = YGUnitPoint) {
if (std::isnan(value)) {
if (!std::isfinite(value)) {
return YGValueUndefined;
}

Expand Down

0 comments on commit 099e7aa

Please sign in to comment.