123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- /*
- * 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.
- */
- #import "RCTShadowView.h"
- #import "RCTConvert.h"
- #import "RCTI18nUtil.h"
- #import "RCTLayout.h"
- #import "RCTLog.h"
- #import "RCTShadowView+Layout.h"
- #import "RCTUtils.h"
- #import "UIView+Private.h"
- #import "UIView+React.h"
- typedef void (^RCTActionBlock)(RCTShadowView *shadowViewSelf, id value);
- typedef void (^RCTResetActionBlock)(RCTShadowView *shadowViewSelf);
- typedef NS_ENUM(unsigned int, meta_prop_t) {
- META_PROP_LEFT,
- META_PROP_TOP,
- META_PROP_RIGHT,
- META_PROP_BOTTOM,
- META_PROP_START,
- META_PROP_END,
- META_PROP_HORIZONTAL,
- META_PROP_VERTICAL,
- META_PROP_ALL,
- META_PROP_COUNT,
- };
- @implementation RCTShadowView {
- NSDictionary *_lastParentProperties;
- NSMutableArray<RCTShadowView *> *_reactSubviews;
- BOOL _recomputePadding;
- BOOL _recomputeMargin;
- BOOL _recomputeBorder;
- YGValue _paddingMetaProps[META_PROP_COUNT];
- YGValue _marginMetaProps[META_PROP_COUNT];
- YGValue _borderMetaProps[META_PROP_COUNT];
- }
- + (YGConfigRef)yogaConfig
- {
- static YGConfigRef yogaConfig;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- yogaConfig = YGConfigNew();
- YGConfigSetPointScaleFactor(yogaConfig, RCTScreenScale());
- YGConfigSetUseLegacyStretchBehaviour(yogaConfig, true);
- });
- return yogaConfig;
- }
- @synthesize reactTag = _reactTag;
- @synthesize rootTag = _rootTag;
- // YogaNode API
- static void RCTPrint(YGNodeRef node)
- {
- RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node);
- printf("%s(%lld), ", shadowView.viewName.UTF8String, (long long)shadowView.reactTag.integerValue);
- }
- #define RCT_SET_YGVALUE(ygvalue, setter, ...) \
- switch (ygvalue.unit) { \
- case YGUnitAuto: \
- case YGUnitUndefined: \
- setter(__VA_ARGS__, YGUndefined); \
- break; \
- case YGUnitPoint: \
- setter(__VA_ARGS__, ygvalue.value); \
- break; \
- case YGUnitPercent: \
- setter##Percent(__VA_ARGS__, ygvalue.value); \
- break; \
- }
- #define RCT_SET_YGVALUE_AUTO(ygvalue, setter, ...) \
- switch (ygvalue.unit) { \
- case YGUnitAuto: \
- setter##Auto(__VA_ARGS__); \
- break; \
- case YGUnitUndefined: \
- setter(__VA_ARGS__, YGUndefined); \
- break; \
- case YGUnitPoint: \
- setter(__VA_ARGS__, ygvalue.value); \
- break; \
- case YGUnitPercent: \
- setter##Percent(__VA_ARGS__, ygvalue.value); \
- break; \
- }
- static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node)
- {
- if (![[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
- RCT_SET_YGVALUE(metaProps[META_PROP_START], YGNodeStyleSetPadding, node, YGEdgeStart);
- RCT_SET_YGVALUE(metaProps[META_PROP_END], YGNodeStyleSetPadding, node, YGEdgeEnd);
- RCT_SET_YGVALUE(metaProps[META_PROP_LEFT], YGNodeStyleSetPadding, node, YGEdgeLeft);
- RCT_SET_YGVALUE(metaProps[META_PROP_RIGHT], YGNodeStyleSetPadding, node, YGEdgeRight);
- } else {
- YGValue start =
- metaProps[META_PROP_START].unit == YGUnitUndefined ? metaProps[META_PROP_LEFT] : metaProps[META_PROP_START];
- YGValue end =
- metaProps[META_PROP_END].unit == YGUnitUndefined ? metaProps[META_PROP_RIGHT] : metaProps[META_PROP_END];
- RCT_SET_YGVALUE(start, YGNodeStyleSetPadding, node, YGEdgeStart);
- RCT_SET_YGVALUE(end, YGNodeStyleSetPadding, node, YGEdgeEnd);
- }
- RCT_SET_YGVALUE(metaProps[META_PROP_TOP], YGNodeStyleSetPadding, node, YGEdgeTop);
- RCT_SET_YGVALUE(metaProps[META_PROP_BOTTOM], YGNodeStyleSetPadding, node, YGEdgeBottom);
- RCT_SET_YGVALUE(metaProps[META_PROP_HORIZONTAL], YGNodeStyleSetPadding, node, YGEdgeHorizontal);
- RCT_SET_YGVALUE(metaProps[META_PROP_VERTICAL], YGNodeStyleSetPadding, node, YGEdgeVertical);
- RCT_SET_YGVALUE(metaProps[META_PROP_ALL], YGNodeStyleSetPadding, node, YGEdgeAll);
- }
- static void RCTProcessMetaPropsMargin(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node)
- {
- if (![[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_START], YGNodeStyleSetMargin, node, YGEdgeStart);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_END], YGNodeStyleSetMargin, node, YGEdgeEnd);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_LEFT], YGNodeStyleSetMargin, node, YGEdgeLeft);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_RIGHT], YGNodeStyleSetMargin, node, YGEdgeRight);
- } else {
- YGValue start =
- metaProps[META_PROP_START].unit == YGUnitUndefined ? metaProps[META_PROP_LEFT] : metaProps[META_PROP_START];
- YGValue end =
- metaProps[META_PROP_END].unit == YGUnitUndefined ? metaProps[META_PROP_RIGHT] : metaProps[META_PROP_END];
- RCT_SET_YGVALUE_AUTO(start, YGNodeStyleSetMargin, node, YGEdgeStart);
- RCT_SET_YGVALUE_AUTO(end, YGNodeStyleSetMargin, node, YGEdgeEnd);
- }
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_TOP], YGNodeStyleSetMargin, node, YGEdgeTop);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_BOTTOM], YGNodeStyleSetMargin, node, YGEdgeBottom);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_HORIZONTAL], YGNodeStyleSetMargin, node, YGEdgeHorizontal);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_VERTICAL], YGNodeStyleSetMargin, node, YGEdgeVertical);
- RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_ALL], YGNodeStyleSetMargin, node, YGEdgeAll);
- }
- static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node)
- {
- if (![[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
- YGNodeStyleSetBorder(node, YGEdgeStart, metaProps[META_PROP_START].value);
- YGNodeStyleSetBorder(node, YGEdgeEnd, metaProps[META_PROP_END].value);
- YGNodeStyleSetBorder(node, YGEdgeLeft, metaProps[META_PROP_LEFT].value);
- YGNodeStyleSetBorder(node, YGEdgeRight, metaProps[META_PROP_RIGHT].value);
- } else {
- const float start = YGFloatIsUndefined(metaProps[META_PROP_START].value) ? metaProps[META_PROP_LEFT].value
- : metaProps[META_PROP_START].value;
- const float end = YGFloatIsUndefined(metaProps[META_PROP_END].value) ? metaProps[META_PROP_RIGHT].value
- : metaProps[META_PROP_END].value;
- YGNodeStyleSetBorder(node, YGEdgeStart, start);
- YGNodeStyleSetBorder(node, YGEdgeEnd, end);
- }
- YGNodeStyleSetBorder(node, YGEdgeTop, metaProps[META_PROP_TOP].value);
- YGNodeStyleSetBorder(node, YGEdgeBottom, metaProps[META_PROP_BOTTOM].value);
- YGNodeStyleSetBorder(node, YGEdgeHorizontal, metaProps[META_PROP_HORIZONTAL].value);
- YGNodeStyleSetBorder(node, YGEdgeVertical, metaProps[META_PROP_VERTICAL].value);
- YGNodeStyleSetBorder(node, YGEdgeAll, metaProps[META_PROP_ALL].value);
- }
- - (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor
- {
- CGPoint offset = CGPointZero;
- RCTShadowView *shadowView = self;
- while (shadowView && shadowView != ancestor) {
- offset.x += shadowView.layoutMetrics.frame.origin.x;
- offset.y += shadowView.layoutMetrics.frame.origin.y;
- shadowView = shadowView->_superview;
- }
- if (ancestor != shadowView) {
- return CGRectNull;
- }
- return (CGRect){offset, self.layoutMetrics.frame.size};
- }
- - (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor
- {
- RCTShadowView *shadowView = self;
- while (shadowView && shadowView != ancestor) {
- shadowView = shadowView->_superview;
- }
- return ancestor == shadowView;
- }
- - (instancetype)init
- {
- if (self = [super init]) {
- for (unsigned int ii = 0; ii < META_PROP_COUNT; ii++) {
- _paddingMetaProps[ii] = YGValueUndefined;
- _marginMetaProps[ii] = YGValueUndefined;
- _borderMetaProps[ii] = YGValueUndefined;
- }
- _intrinsicContentSize = CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
- _newView = YES;
- _reactSubviews = [NSMutableArray array];
- _yogaNode = YGNodeNewWithConfig([[self class] yogaConfig]);
- YGNodeSetContext(_yogaNode, (__bridge void *)self);
- YGNodeSetPrintFunc(_yogaNode, RCTPrint);
- }
- return self;
- }
- - (BOOL)isReactRootView
- {
- return RCTIsReactRootView(self.reactTag);
- }
- - (void)dealloc
- {
- YGNodeFree(_yogaNode);
- }
- - (BOOL)canHaveSubviews
- {
- return YES;
- }
- - (BOOL)isYogaLeafNode
- {
- return NO;
- }
- - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
- {
- RCTAssert(self.canHaveSubviews, @"Attempt to insert subview inside leaf view.");
- [_reactSubviews insertObject:subview atIndex:atIndex];
- if (![self isYogaLeafNode]) {
- YGNodeInsertChild(_yogaNode, subview.yogaNode, (uint32_t)atIndex);
- }
- subview->_superview = self;
- }
- - (void)removeReactSubview:(RCTShadowView *)subview
- {
- subview->_superview = nil;
- [_reactSubviews removeObject:subview];
- if (![self isYogaLeafNode]) {
- YGNodeRemoveChild(_yogaNode, subview.yogaNode);
- }
- }
- - (NSArray<RCTShadowView *> *)reactSubviews
- {
- return _reactSubviews;
- }
- - (RCTShadowView *)reactSuperview
- {
- return _superview;
- }
- #pragma mark - Layout
- - (void)layoutWithMinimumSize:(CGSize)minimumSize
- maximumSize:(CGSize)maximumSize
- layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection
- layoutContext:(RCTLayoutContext)layoutContext
- {
- YGNodeRef yogaNode = _yogaNode;
- CGSize oldMinimumSize = (CGSize){RCTCoreGraphicsFloatFromYogaValue(YGNodeStyleGetMinWidth(yogaNode), 0.0),
- RCTCoreGraphicsFloatFromYogaValue(YGNodeStyleGetMinHeight(yogaNode), 0.0)};
- if (!CGSizeEqualToSize(oldMinimumSize, minimumSize)) {
- YGNodeStyleSetMinWidth(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width));
- YGNodeStyleSetMinHeight(yogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height));
- }
- YGNodeCalculateLayout(
- yogaNode,
- RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width),
- RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height),
- RCTYogaLayoutDirectionFromUIKitLayoutDirection(layoutDirection));
- RCTAssert(!YGNodeIsDirty(yogaNode), @"Attempt to get layout metrics from dirtied Yoga node.");
- if (!YGNodeGetHasNewLayout(yogaNode)) {
- return;
- }
- YGNodeSetHasNewLayout(yogaNode, false);
- RCTLayoutMetrics layoutMetrics = RCTLayoutMetricsFromYogaNode(yogaNode);
- layoutContext.absolutePosition.x += layoutMetrics.frame.origin.x;
- layoutContext.absolutePosition.y += layoutMetrics.frame.origin.y;
- [self layoutWithMetrics:layoutMetrics layoutContext:layoutContext];
- [self layoutSubviewsWithContext:layoutContext];
- }
- - (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext
- {
- if (!RCTLayoutMetricsEqualToLayoutMetrics(self.layoutMetrics, layoutMetrics)) {
- self.layoutMetrics = layoutMetrics;
- [layoutContext.affectedShadowViews addObject:self];
- }
- }
- - (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext
- {
- RCTLayoutMetrics layoutMetrics = self.layoutMetrics;
- if (layoutMetrics.displayType == RCTDisplayTypeNone) {
- return;
- }
- for (RCTShadowView *childShadowView in _reactSubviews) {
- YGNodeRef childYogaNode = childShadowView.yogaNode;
- RCTAssert(!YGNodeIsDirty(childYogaNode), @"Attempt to get layout metrics from dirtied Yoga node.");
- if (!YGNodeGetHasNewLayout(childYogaNode)) {
- continue;
- }
- YGNodeSetHasNewLayout(childYogaNode, false);
- RCTLayoutMetrics childLayoutMetrics = RCTLayoutMetricsFromYogaNode(childYogaNode);
- layoutContext.absolutePosition.x += childLayoutMetrics.frame.origin.x;
- layoutContext.absolutePosition.y += childLayoutMetrics.frame.origin.y;
- [childShadowView layoutWithMetrics:childLayoutMetrics layoutContext:layoutContext];
- // Recursive call.
- [childShadowView layoutSubviewsWithContext:layoutContext];
- }
- }
- - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
- {
- YGNodeRef clonedYogaNode = YGNodeClone(self.yogaNode);
- YGNodeRef constraintYogaNode = YGNodeNewWithConfig([[self class] yogaConfig]);
- YGNodeInsertChild(constraintYogaNode, clonedYogaNode, 0);
- YGNodeStyleSetMinWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.width));
- YGNodeStyleSetMinHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(minimumSize.height));
- YGNodeStyleSetMaxWidth(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.width));
- YGNodeStyleSetMaxHeight(constraintYogaNode, RCTYogaFloatFromCoreGraphicsFloat(maximumSize.height));
- YGNodeCalculateLayout(
- constraintYogaNode,
- YGUndefined,
- YGUndefined,
- RCTYogaLayoutDirectionFromUIKitLayoutDirection(self.layoutMetrics.layoutDirection));
- CGSize measuredSize = (CGSize){
- RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetWidth(constraintYogaNode)),
- RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetHeight(constraintYogaNode)),
- };
- YGNodeRemoveChild(constraintYogaNode, clonedYogaNode);
- YGNodeFree(constraintYogaNode);
- YGNodeFree(clonedYogaNode);
- return measuredSize;
- }
- - (NSNumber *)reactTagAtPoint:(CGPoint)point
- {
- for (RCTShadowView *shadowView in _reactSubviews) {
- if (CGRectContainsPoint(shadowView.layoutMetrics.frame, point)) {
- CGPoint relativePoint = point;
- CGPoint origin = shadowView.layoutMetrics.frame.origin;
- relativePoint.x -= origin.x;
- relativePoint.y -= origin.y;
- return [shadowView reactTagAtPoint:relativePoint];
- }
- }
- return self.reactTag;
- }
- - (NSString *)description
- {
- NSString *description = super.description;
- description = [[description substringToIndex:description.length - 1]
- stringByAppendingFormat:@"; viewName: %@; reactTag: %@; frame: %@>",
- self.viewName,
- self.reactTag,
- NSStringFromCGRect(self.layoutMetrics.frame)];
- return description;
- }
- - (void)addRecursiveDescriptionToString:(NSMutableString *)string atLevel:(NSUInteger)level
- {
- for (NSUInteger i = 0; i < level; i++) {
- [string appendString:@" | "];
- }
- [string appendString:self.description];
- [string appendString:@"\n"];
- for (RCTShadowView *subview in _reactSubviews) {
- [subview addRecursiveDescriptionToString:string atLevel:level + 1];
- }
- }
- - (NSString *)recursiveDescription
- {
- NSMutableString *description = [NSMutableString string];
- [self addRecursiveDescriptionToString:description atLevel:0];
- return description;
- }
- // Margin
- #define RCT_MARGIN_PROPERTY(prop, metaProp) \
- -(void)setMargin##prop : (YGValue)value \
- { \
- _marginMetaProps[META_PROP_##metaProp] = value; \
- _recomputeMargin = YES; \
- } \
- -(YGValue)margin##prop \
- { \
- return _marginMetaProps[META_PROP_##metaProp]; \
- }
- RCT_MARGIN_PROPERTY(, ALL)
- RCT_MARGIN_PROPERTY(Vertical, VERTICAL)
- RCT_MARGIN_PROPERTY(Horizontal, HORIZONTAL)
- RCT_MARGIN_PROPERTY(Top, TOP)
- RCT_MARGIN_PROPERTY(Left, LEFT)
- RCT_MARGIN_PROPERTY(Bottom, BOTTOM)
- RCT_MARGIN_PROPERTY(Right, RIGHT)
- RCT_MARGIN_PROPERTY(Start, START)
- RCT_MARGIN_PROPERTY(End, END)
- // Padding
- #define RCT_PADDING_PROPERTY(prop, metaProp) \
- -(void)setPadding##prop : (YGValue)value \
- { \
- _paddingMetaProps[META_PROP_##metaProp] = value; \
- _recomputePadding = YES; \
- } \
- -(YGValue)padding##prop \
- { \
- return _paddingMetaProps[META_PROP_##metaProp]; \
- }
- RCT_PADDING_PROPERTY(, ALL)
- RCT_PADDING_PROPERTY(Vertical, VERTICAL)
- RCT_PADDING_PROPERTY(Horizontal, HORIZONTAL)
- RCT_PADDING_PROPERTY(Top, TOP)
- RCT_PADDING_PROPERTY(Left, LEFT)
- RCT_PADDING_PROPERTY(Bottom, BOTTOM)
- RCT_PADDING_PROPERTY(Right, RIGHT)
- RCT_PADDING_PROPERTY(Start, START)
- RCT_PADDING_PROPERTY(End, END)
- // Border
- #define RCT_BORDER_PROPERTY(prop, metaProp) \
- -(void)setBorder##prop##Width : (float)value \
- { \
- _borderMetaProps[META_PROP_##metaProp].value = value; \
- _recomputeBorder = YES; \
- } \
- -(float)border##prop##Width \
- { \
- return _borderMetaProps[META_PROP_##metaProp].value; \
- }
- RCT_BORDER_PROPERTY(, ALL)
- RCT_BORDER_PROPERTY(Top, TOP)
- RCT_BORDER_PROPERTY(Left, LEFT)
- RCT_BORDER_PROPERTY(Bottom, BOTTOM)
- RCT_BORDER_PROPERTY(Right, RIGHT)
- RCT_BORDER_PROPERTY(Start, START)
- RCT_BORDER_PROPERTY(End, END)
- // Dimensions
- #define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
- -(void)set##setProp : (YGValue)value \
- { \
- RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \
- } \
- -(YGValue)getProp \
- { \
- return YGNodeStyleGet##cssProp(_yogaNode); \
- }
- #define RCT_MIN_MAX_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
- -(void)set##setProp : (YGValue)value \
- { \
- RCT_SET_YGVALUE(value, YGNodeStyleSet##cssProp, _yogaNode); \
- } \
- -(YGValue)getProp \
- { \
- return YGNodeStyleGet##cssProp(_yogaNode); \
- }
- RCT_DIMENSION_PROPERTY(Width, width, Width)
- RCT_DIMENSION_PROPERTY(Height, height, Height)
- RCT_MIN_MAX_DIMENSION_PROPERTY(MinWidth, minWidth, MinWidth)
- RCT_MIN_MAX_DIMENSION_PROPERTY(MinHeight, minHeight, MinHeight)
- RCT_MIN_MAX_DIMENSION_PROPERTY(MaxWidth, maxWidth, MaxWidth)
- RCT_MIN_MAX_DIMENSION_PROPERTY(MaxHeight, maxHeight, MaxHeight)
- // Position
- #define RCT_POSITION_PROPERTY(setProp, getProp, edge) \
- -(void)set##setProp : (YGValue)value \
- { \
- RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge); \
- } \
- -(YGValue)getProp \
- { \
- return YGNodeStyleGetPosition(_yogaNode, edge); \
- }
- RCT_POSITION_PROPERTY(Top, top, YGEdgeTop)
- RCT_POSITION_PROPERTY(Bottom, bottom, YGEdgeBottom)
- RCT_POSITION_PROPERTY(Start, start, YGEdgeStart)
- RCT_POSITION_PROPERTY(End, end, YGEdgeEnd)
- - (void)setLeft:(YGValue)value
- {
- YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeStart : YGEdgeLeft;
- RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge);
- }
- - (YGValue)left
- {
- YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeStart : YGEdgeLeft;
- return YGNodeStyleGetPosition(_yogaNode, edge);
- }
- - (void)setRight:(YGValue)value
- {
- YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeEnd : YGEdgeRight;
- RCT_SET_YGVALUE(value, YGNodeStyleSetPosition, _yogaNode, edge);
- }
- - (YGValue)right
- {
- YGEdge edge = [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL] ? YGEdgeEnd : YGEdgeRight;
- return YGNodeStyleGetPosition(_yogaNode, edge);
- }
- // Size
- - (CGSize)size
- {
- YGValue width = YGNodeStyleGetWidth(_yogaNode);
- YGValue height = YGNodeStyleGetHeight(_yogaNode);
- return CGSizeMake(width.unit == YGUnitPoint ? width.value : NAN, height.unit == YGUnitPoint ? height.value : NAN);
- }
- - (void)setSize:(CGSize)size
- {
- YGNodeStyleSetWidth(_yogaNode, size.width);
- YGNodeStyleSetHeight(_yogaNode, size.height);
- }
- // IntrinsicContentSize
- static inline YGSize
- RCTShadowViewMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
- {
- RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext(node);
- CGSize intrinsicContentSize = shadowView->_intrinsicContentSize;
- // Replace `UIViewNoIntrinsicMetric` (which equals `-1`) with zero.
- intrinsicContentSize.width = MAX(0, intrinsicContentSize.width);
- intrinsicContentSize.height = MAX(0, intrinsicContentSize.height);
- YGSize result;
- switch (widthMode) {
- case YGMeasureModeUndefined:
- result.width = intrinsicContentSize.width;
- break;
- case YGMeasureModeExactly:
- result.width = width;
- break;
- case YGMeasureModeAtMost:
- result.width = MIN(width, intrinsicContentSize.width);
- break;
- }
- switch (heightMode) {
- case YGMeasureModeUndefined:
- result.height = intrinsicContentSize.height;
- break;
- case YGMeasureModeExactly:
- result.height = height;
- break;
- case YGMeasureModeAtMost:
- result.height = MIN(height, intrinsicContentSize.height);
- break;
- }
- return result;
- }
- - (void)setIntrinsicContentSize:(CGSize)intrinsicContentSize
- {
- if (CGSizeEqualToSize(_intrinsicContentSize, intrinsicContentSize)) {
- return;
- }
- _intrinsicContentSize = intrinsicContentSize;
- if (CGSizeEqualToSize(_intrinsicContentSize, CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric))) {
- YGNodeSetMeasureFunc(_yogaNode, NULL);
- } else {
- YGNodeSetMeasureFunc(_yogaNode, RCTShadowViewMeasure);
- }
- YGNodeMarkDirty(_yogaNode);
- }
- // Local Data
- - (void)setLocalData:(__unused NSObject *)localData
- {
- // Do nothing by default.
- }
- // Flex
- - (void)setFlexBasis:(YGValue)value
- {
- RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSetFlexBasis, _yogaNode);
- }
- - (YGValue)flexBasis
- {
- return YGNodeStyleGetFlexBasis(_yogaNode);
- }
- #define RCT_STYLE_PROPERTY(setProp, getProp, cssProp, type) \
- -(void)set##setProp : (type)value \
- { \
- YGNodeStyleSet##cssProp(_yogaNode, value); \
- } \
- -(type)getProp \
- { \
- return YGNodeStyleGet##cssProp(_yogaNode); \
- }
- RCT_STYLE_PROPERTY(Flex, flex, Flex, float)
- RCT_STYLE_PROPERTY(FlexGrow, flexGrow, FlexGrow, float)
- RCT_STYLE_PROPERTY(FlexShrink, flexShrink, FlexShrink, float)
- RCT_STYLE_PROPERTY(FlexDirection, flexDirection, FlexDirection, YGFlexDirection)
- RCT_STYLE_PROPERTY(JustifyContent, justifyContent, JustifyContent, YGJustify)
- RCT_STYLE_PROPERTY(AlignSelf, alignSelf, AlignSelf, YGAlign)
- RCT_STYLE_PROPERTY(AlignItems, alignItems, AlignItems, YGAlign)
- RCT_STYLE_PROPERTY(AlignContent, alignContent, AlignContent, YGAlign)
- RCT_STYLE_PROPERTY(Position, position, PositionType, YGPositionType)
- RCT_STYLE_PROPERTY(FlexWrap, flexWrap, FlexWrap, YGWrap)
- RCT_STYLE_PROPERTY(Overflow, overflow, Overflow, YGOverflow)
- RCT_STYLE_PROPERTY(Display, display, Display, YGDisplay)
- RCT_STYLE_PROPERTY(Direction, direction, Direction, YGDirection)
- RCT_STYLE_PROPERTY(AspectRatio, aspectRatio, AspectRatio, float)
- - (void)didUpdateReactSubviews
- {
- // Does nothing by default
- }
- - (void)didSetProps:(__unused NSArray<NSString *> *)changedProps
- {
- if (_recomputePadding) {
- RCTProcessMetaPropsPadding(_paddingMetaProps, _yogaNode);
- }
- if (_recomputeMargin) {
- RCTProcessMetaPropsMargin(_marginMetaProps, _yogaNode);
- }
- if (_recomputeBorder) {
- RCTProcessMetaPropsBorder(_borderMetaProps, _yogaNode);
- }
- _recomputeMargin = NO;
- _recomputePadding = NO;
- _recomputeBorder = NO;
- }
- @end
|