mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 01:25:39 +00:00
f91f7d91a1
Summary: This is reimagining of interoperability layer between Yoga and ShadowViews (at least in Yoga -> RN part). Goals: * Make it clear and easy. * Make clear separation between "what layout what", now parent always layout children, noone layout itself. * Make possible to interleave Yoga layout with custom imperative layout (may be used in SafeAreaView, Text, Modal, InputAccessoryView and so on). Reviewed By: mmmulani Differential Revision: D6863654 fbshipit-source-id: 5a6a933874f121d46f744aab99a31ae42ddd4a1b
146 lines
4.4 KiB
Objective-C
146 lines
4.4 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import <yoga/Yoga.h>
|
|
|
|
#import "RCTAssert.h"
|
|
#import "RCTShadowView+Layout.h"
|
|
|
|
RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode)
|
|
{
|
|
RCTLayoutMetrics layoutMetrics;
|
|
|
|
CGRect frame = (CGRect){
|
|
(CGPoint){
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetLeft(yogaNode)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetTop(yogaNode))
|
|
},
|
|
(CGSize){
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetWidth(yogaNode)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetHeight(yogaNode))
|
|
}
|
|
};
|
|
|
|
UIEdgeInsets padding = (UIEdgeInsets){
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight))
|
|
};
|
|
|
|
UIEdgeInsets borderWidth = (UIEdgeInsets){
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)),
|
|
RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight))
|
|
};
|
|
|
|
UIEdgeInsets compoundInsets = (UIEdgeInsets){
|
|
borderWidth.top + padding.top,
|
|
borderWidth.left + padding.left,
|
|
borderWidth.bottom + padding.bottom,
|
|
borderWidth.right + padding.right
|
|
};
|
|
|
|
CGRect bounds = (CGRect){CGPointZero, frame.size};
|
|
CGRect contentFrame = UIEdgeInsetsInsetRect(bounds, compoundInsets);
|
|
|
|
layoutMetrics.frame = frame;
|
|
layoutMetrics.borderWidth = borderWidth;
|
|
layoutMetrics.contentFrame = contentFrame;
|
|
layoutMetrics.displayType = RCTReactDisplayTypeFromYogaDisplayType(YGNodeStyleGetDisplay(yogaNode));
|
|
layoutMetrics.layoutDirection = RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGNodeLayoutGetDirection(yogaNode));
|
|
|
|
return layoutMetrics;
|
|
}
|
|
|
|
|
|
/**
|
|
* Yoga and CoreGraphics have different opinions about how "infinity" value
|
|
* should be represented.
|
|
* Yoga uses `NAN` which requires additional effort to compare all those values,
|
|
* whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with
|
|
* standard `==` operator.
|
|
*/
|
|
|
|
float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value)
|
|
{
|
|
if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) {
|
|
return YGUndefined;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value)
|
|
{
|
|
if (value == YGUndefined || isnan(value) || isinf(value)) {
|
|
return CGFLOAT_MAX;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue)
|
|
{
|
|
switch (value.unit) {
|
|
case YGUnitPoint:
|
|
return RCTCoreGraphicsFloatFromYogaFloat(value.value);
|
|
case YGUnitPercent:
|
|
return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue;
|
|
case YGUnitAuto:
|
|
case YGUnitUndefined:
|
|
return baseFloatValue;
|
|
}
|
|
}
|
|
|
|
YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction)
|
|
{
|
|
switch (direction) {
|
|
case UIUserInterfaceLayoutDirectionRightToLeft:
|
|
return YGDirectionRTL;
|
|
case UIUserInterfaceLayoutDirectionLeftToRight:
|
|
return YGDirectionLTR;
|
|
}
|
|
}
|
|
|
|
UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction)
|
|
{
|
|
switch (direction) {
|
|
case YGDirectionInherit:
|
|
case YGDirectionLTR:
|
|
return UIUserInterfaceLayoutDirectionLeftToRight;
|
|
case YGDirectionRTL:
|
|
return UIUserInterfaceLayoutDirectionRightToLeft;
|
|
}
|
|
}
|
|
|
|
YGDisplay RCTYogaDisplayTypeFromReactDisplayType(RCTDisplayType displayType)
|
|
{
|
|
switch (displayType) {
|
|
case RCTDisplayTypeNone:
|
|
return YGDisplayNone;
|
|
case RCTDisplayTypeFlex:
|
|
return YGDisplayFlex;
|
|
case RCTDisplayTypeInline:
|
|
RCTAssert(NO, @"RCTDisplayTypeInline cannot be converted to YGDisplay value.");
|
|
return YGDisplayNone;
|
|
}
|
|
}
|
|
|
|
RCTDisplayType RCTReactDisplayTypeFromYogaDisplayType(YGDisplay displayType)
|
|
{
|
|
switch (displayType) {
|
|
case YGDisplayFlex:
|
|
return RCTDisplayTypeFlex;
|
|
case YGDisplayNone:
|
|
return RCTDisplayTypeNone;
|
|
}
|
|
}
|