mirror of
https://github.com/status-im/react-native.git
synced 2025-02-26 08:05:34 +00:00
Revamp API
Reviewed By: majak Differential Revision: D3579423 fbshipit-source-id: 040ecab2f20216aa136ccb8a9e7e15ffa882b313
This commit is contained in:
parent
12ec213c0d
commit
1af9270e45
@ -28,10 +28,10 @@
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
self.parentView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flexDirection = CSSFlexDirectionColumn;
|
||||
style->dimensions[0] = 440;
|
||||
style->dimensions[1] = 440;
|
||||
self.parentView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlexDirection(node, CSSFlexDirectionColumn);
|
||||
CSSNodeStyleSetWidth(node, 440);
|
||||
CSSNodeStyleSetHeight(node, 440);
|
||||
}];
|
||||
self.parentView.reactTag = @1; // must be valid rootView tag
|
||||
}
|
||||
@ -50,43 +50,43 @@
|
||||
//
|
||||
- (void)testApplyingLayoutRecursivelyToShadowView
|
||||
{
|
||||
RCTShadowView *leftView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 1;
|
||||
RCTShadowView *leftView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 1);
|
||||
}];
|
||||
|
||||
RCTShadowView *centerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 2;
|
||||
style->margin[0] = 10;
|
||||
style->margin[2] = 10;
|
||||
RCTShadowView *centerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 2);
|
||||
CSSNodeStyleSetMarginLeft(node, 10);
|
||||
CSSNodeStyleSetMarginRight(node, 10);
|
||||
}];
|
||||
|
||||
RCTShadowView *rightView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 1;
|
||||
RCTShadowView *rightView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 1);
|
||||
}];
|
||||
|
||||
RCTShadowView *mainView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flexDirection = CSSFlexDirectionRow;
|
||||
style->flex = 2;
|
||||
style->margin[1] = 10;
|
||||
style->margin[3] = 10;
|
||||
RCTShadowView *mainView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlexDirection(node, CSSFlexDirectionRow);
|
||||
CSSNodeStyleSetFlex(node, 2);
|
||||
CSSNodeStyleSetMarginTop(node, 10);
|
||||
CSSNodeStyleSetMarginBottom(node, 10);
|
||||
}];
|
||||
|
||||
[mainView insertReactSubview:leftView atIndex:0];
|
||||
[mainView insertReactSubview:centerView atIndex:1];
|
||||
[mainView insertReactSubview:rightView atIndex:2];
|
||||
|
||||
RCTShadowView *headerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 1;
|
||||
RCTShadowView *headerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 1);
|
||||
}];
|
||||
|
||||
RCTShadowView *footerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 1;
|
||||
RCTShadowView *footerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 1);
|
||||
}];
|
||||
|
||||
self.parentView.cssNode->style.padding[0] = 10;
|
||||
self.parentView.cssNode->style.padding[1] = 10;
|
||||
self.parentView.cssNode->style.padding[2] = 10;
|
||||
self.parentView.cssNode->style.padding[3] = 10;
|
||||
CSSNodeStyleSetPaddingLeft(self.parentView.cssNode, 10);
|
||||
CSSNodeStyleSetPaddingTop(self.parentView.cssNode, 10);
|
||||
CSSNodeStyleSetPaddingRight(self.parentView.cssNode, 10);
|
||||
CSSNodeStyleSetPaddingBottom(self.parentView.cssNode, 10);
|
||||
|
||||
[self.parentView insertReactSubview:headerView atIndex:0];
|
||||
[self.parentView insertReactSubview:mainView atIndex:1];
|
||||
@ -108,10 +108,10 @@
|
||||
|
||||
- (void)testAssignsSuggestedWidthDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->position[CSSPositionLeft] = 0;
|
||||
style->position[CSSPositionTop] = 0;
|
||||
style->dimensions[CSSDimensionHeight] = 10;
|
||||
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetPositionLeft(node, 0);
|
||||
CSSNodeStyleSetPositionTop(node, 0);
|
||||
CSSNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 3, 10)
|
||||
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
|
||||
@ -119,10 +119,10 @@
|
||||
|
||||
- (void)testAssignsSuggestedHeightDimension
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->position[CSSPositionLeft] = 0;
|
||||
style->position[CSSPositionTop] = 0;
|
||||
style->dimensions[CSSDimensionWidth] = 10;
|
||||
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetPositionLeft(node, 0);
|
||||
CSSNodeStyleSetPositionTop(node, 0);
|
||||
CSSNodeStyleSetWidth(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 10, 4)
|
||||
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
|
||||
@ -130,11 +130,11 @@
|
||||
|
||||
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
||||
{
|
||||
[self _withShadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->position[CSSPositionLeft] = 0;
|
||||
style->position[CSSPositionTop] = 0;
|
||||
style->dimensions[CSSDimensionWidth] = 10;
|
||||
style->dimensions[CSSDimensionHeight] = 10;
|
||||
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetPositionLeft(node, 0);
|
||||
CSSNodeStyleSetPositionTop(node, 0);
|
||||
CSSNodeStyleSetWidth(node, 10);
|
||||
CSSNodeStyleSetHeight(node, 10);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, 10, 10)
|
||||
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
||||
@ -142,20 +142,20 @@
|
||||
|
||||
- (void)testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute
|
||||
{
|
||||
float parentWidth = self.parentView.cssNode->style.dimensions[CSSDimensionWidth];
|
||||
float parentHeight = self.parentView.cssNode->style.dimensions[CSSDimensionHeight];
|
||||
[self _withShadowViewWithStyle:^(CSSStyle *style) {
|
||||
style->flex = 1;
|
||||
float parentWidth = CSSNodeStyleGetWidth(self.parentView.cssNode);
|
||||
float parentHeight = CSSNodeStyleGetHeight(self.parentView.cssNode);
|
||||
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
||||
CSSNodeStyleSetFlex(node, 1);
|
||||
}
|
||||
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
|
||||
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
||||
}
|
||||
|
||||
- (void)_withShadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock
|
||||
- (void)_withShadowViewWithStyle:(void(^)(CSSNodeRef node))configBlock
|
||||
assertRelativeLayout:(CGRect)expectedRect
|
||||
withIntrinsicContentSize:(CGSize)contentSize
|
||||
{
|
||||
RCTShadowView *view = [self _shadowViewWithStyle:styleBlock];
|
||||
RCTShadowView *view = [self _shadowViewWithConfig:configBlock];
|
||||
[self.parentView insertReactSubview:view atIndex:0];
|
||||
view.intrinsicContentSize = contentSize;
|
||||
[self.parentView collectViewsWithUpdatedFrames];
|
||||
@ -166,14 +166,10 @@
|
||||
NSStringFromCGRect(actualRect));
|
||||
}
|
||||
|
||||
- (RCTRootShadowView *)_shadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock
|
||||
- (RCTRootShadowView *)_shadowViewWithConfig:(void(^)(CSSNodeRef node))configBlock
|
||||
{
|
||||
RCTRootShadowView *shadowView = [RCTRootShadowView new];
|
||||
|
||||
CSSStyle style = shadowView.cssNode->style;
|
||||
styleBlock(&style);
|
||||
shadowView.cssNode->style = style;
|
||||
|
||||
configBlock(shadowView.cssNode);
|
||||
return shadowView;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ NSString *const RCTReactTagAttributeName = @"ReactTagAttributeName";
|
||||
CGFloat _effectiveLetterSpacing;
|
||||
}
|
||||
|
||||
static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
|
||||
static CSSSize RCTMeasure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
|
||||
{
|
||||
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
|
||||
NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode];
|
||||
@ -41,12 +41,12 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
||||
CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
|
||||
|
||||
CSSMeasureResult result;
|
||||
result.dimensions[CSSDimensionWidth] = RCTCeilPixelValue(computedSize.width);
|
||||
CSSSize result;
|
||||
result.width = RCTCeilPixelValue(computedSize.width);
|
||||
if (shadowText->_effectiveLetterSpacing < 0) {
|
||||
result.dimensions[CSSDimensionWidth] -= shadowText->_effectiveLetterSpacing;
|
||||
result.width -= shadowText->_effectiveLetterSpacing;
|
||||
}
|
||||
result.dimensions[CSSDimensionHeight] = RCTCeilPixelValue(computedSize.height);
|
||||
result.height = RCTCeilPixelValue(computedSize.height);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
_cachedTextStorageWidth = -1;
|
||||
_cachedTextStorageWidthMode = -1;
|
||||
_fontSizeMultiplier = 1.0;
|
||||
self.cssNode->measure = RCTMeasure;
|
||||
CSSNodeSetMeasureFunc(self.cssNode, RCTMeasure);
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(contentSizeMultiplierDidChange:)
|
||||
name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification
|
||||
@ -128,7 +128,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
return parentProperties;
|
||||
}
|
||||
|
||||
- (void)applyLayoutNode:(CSSNode *)node
|
||||
- (void)applyLayoutNode:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition
|
||||
{
|
||||
@ -136,7 +136,7 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
[self dirtyPropagation];
|
||||
}
|
||||
|
||||
- (void)applyLayoutToChildren:(CSSNode *)node
|
||||
- (void)applyLayoutToChildren:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition
|
||||
{
|
||||
@ -148,9 +148,9 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
|
||||
[layoutManager.textStorage enumerateAttribute:RCTShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) {
|
||||
if (child) {
|
||||
CSSNode *childNode = child.cssNode;
|
||||
float width = childNode->style.dimensions[CSSDimensionWidth];
|
||||
float height = childNode->style.dimensions[CSSDimensionHeight];
|
||||
CSSNodeRef childNode = child.cssNode;
|
||||
float width = CSSNodeStyleGetWidth(childNode);
|
||||
float height = CSSNodeStyleGetHeight(childNode);
|
||||
if (isUndefined(width) || isUndefined(height)) {
|
||||
RCTLogError(@"Views nested within a <Text> must have a width and height");
|
||||
}
|
||||
@ -291,8 +291,8 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
|
||||
[child setTextComputed];
|
||||
} else {
|
||||
float width = child.cssNode->style.dimensions[CSSDimensionWidth];
|
||||
float height = child.cssNode->style.dimensions[CSSDimensionHeight];
|
||||
float width = CSSNodeStyleGetWidth(child.cssNode);
|
||||
float height = CSSNodeStyleGetHeight(child.cssNode);
|
||||
if (isUndefined(width) || isUndefined(height)) {
|
||||
RCTLogError(@"Views nested within a <Text> must have a width and height");
|
||||
}
|
||||
@ -384,10 +384,10 @@ static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode wi
|
||||
// We will climb up to the first node which style has been setted as non-inherit
|
||||
if (newTextAlign == NSTextAlignmentRight || newTextAlign == NSTextAlignmentLeft) {
|
||||
RCTShadowView *view = self;
|
||||
while (view != nil && view.cssNode->style.direction == CSSDirectionInherit) {
|
||||
while (view != nil && CSSNodeStyleGetDirection(view.cssNode) == CSSDirectionInherit) {
|
||||
view = [view reactSuperview];
|
||||
}
|
||||
if (view != nil && view.cssNode->style.direction == CSSDirectionRTL) {
|
||||
if (view != nil && CSSNodeStyleGetDirection(view.cssNode) == CSSDirectionRTL) {
|
||||
if (newTextAlign == NSTextAlignmentRight) {
|
||||
newTextAlign = NSTextAlignmentLeft;
|
||||
} else if (newTextAlign == NSTextAlignmentLeft) {
|
||||
|
104
React/CSSLayout/CSSLayout-internal.h
Normal file
104
React/CSSLayout/CSSLayout-internal.h
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright (c) 2014-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.
|
||||
*/
|
||||
|
||||
#ifndef __CSS_LAYOUT_INTERNAL_H
|
||||
#define __CSS_LAYOUT_INTERNAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "CSSLayout.h"
|
||||
|
||||
CSS_EXTERN_C_BEGIN
|
||||
|
||||
typedef struct CSSCachedMeasurement {
|
||||
float availableWidth;
|
||||
float availableHeight;
|
||||
CSSMeasureMode widthMeasureMode;
|
||||
CSSMeasureMode heightMeasureMode;
|
||||
|
||||
float computedWidth;
|
||||
float computedHeight;
|
||||
} CSSCachedMeasurement;
|
||||
|
||||
// This value was chosen based on empiracle data. Even the most complicated
|
||||
// layouts should not require more than 16 entries to fit within the cache.
|
||||
enum {
|
||||
CSS_MAX_CACHED_RESULT_COUNT = 16
|
||||
};
|
||||
|
||||
typedef struct CSSLayout {
|
||||
float position[4];
|
||||
float dimensions[2];
|
||||
CSSDirection direction;
|
||||
|
||||
float flexBasis;
|
||||
|
||||
// Instead of recomputing the entire layout every single time, we
|
||||
// cache some information to break early when nothing changed
|
||||
int generationCount;
|
||||
CSSDirection lastParentDirection;
|
||||
|
||||
int nextCachedMeasurementsIndex;
|
||||
CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
|
||||
float measuredDimensions[2];
|
||||
|
||||
CSSCachedMeasurement cached_layout;
|
||||
} CSSLayout;
|
||||
|
||||
typedef struct CSSStyle {
|
||||
CSSDirection direction;
|
||||
CSSFlexDirection flexDirection;
|
||||
CSSJustify justifyContent;
|
||||
CSSAlign alignContent;
|
||||
CSSAlign alignItems;
|
||||
CSSAlign alignSelf;
|
||||
CSSPositionType positionType;
|
||||
CSSWrapType flexWrap;
|
||||
CSSOverflow overflow;
|
||||
float flex;
|
||||
float margin[6];
|
||||
float position[4];
|
||||
/**
|
||||
* You should skip all the rules that contain negative values for the
|
||||
* following attributes. For example:
|
||||
* {padding: 10, paddingLeft: -5}
|
||||
* should output:
|
||||
* {left: 10 ...}
|
||||
* the following two are incorrect:
|
||||
* {left: -5 ...}
|
||||
* {left: 0 ...}
|
||||
*/
|
||||
float padding[6];
|
||||
float border[6];
|
||||
float dimensions[2];
|
||||
float minDimensions[2];
|
||||
float maxDimensions[2];
|
||||
} CSSStyle;
|
||||
|
||||
typedef struct CSSNode {
|
||||
CSSStyle style;
|
||||
CSSLayout layout;
|
||||
int childCount;
|
||||
int lineIndex;
|
||||
bool shouldUpdate;
|
||||
|
||||
struct CSSNode* nextChild;
|
||||
|
||||
CSSSize (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
|
||||
struct CSSNode* (*getChild)(void *context, int i);
|
||||
bool (*isDirty)(void *context);
|
||||
bool (*isTextNode)(void *context);
|
||||
void (*print)(void *context);
|
||||
void *context;
|
||||
} CSSNode;
|
||||
|
||||
CSS_EXTERN_C_END
|
||||
|
||||
#endif
|
@ -13,7 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CSSLayout.h"
|
||||
#include "CSSLayout-internal.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <float.h>
|
||||
@ -29,23 +29,17 @@ __forceinline const float fmaxf(const float a, const float b) {
|
||||
|
||||
#define POSITIVE_FLEX_IS_AUTO 0
|
||||
|
||||
int gCurrentGenerationCount = 0;
|
||||
|
||||
bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection,
|
||||
CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason);
|
||||
|
||||
bool isUndefined(float value) {
|
||||
return isnan(value);
|
||||
CSSNodeRef CSSNodeNew() {
|
||||
CSSNode* node = (CSSNode*)calloc(1, sizeof(*node));
|
||||
CSSNodeInit(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool eq(float a, float b) {
|
||||
if (isUndefined(a)) {
|
||||
return isUndefined(b);
|
||||
}
|
||||
return fabs(a - b) < 0.0001;
|
||||
void CSSNodeFree(CSSNodeRef node) {
|
||||
free(node);
|
||||
}
|
||||
|
||||
void CSSNodeInit(CSSNode* node) {
|
||||
void CSSNodeInit(CSSNodeRef node) {
|
||||
node->style.alignItems = CSSAlignStretch;
|
||||
node->style.alignContent = CSSAlignFlexStart;
|
||||
|
||||
@ -81,7 +75,7 @@ void CSSNodeInit(CSSNode* node) {
|
||||
|
||||
// Such that the comparison is always going to be false
|
||||
node->layout.lastParentDirection = (CSSDirection)-1;
|
||||
node->layout.shouldUpdate = true;
|
||||
node->shouldUpdate = true;
|
||||
node->layout.nextCachedMeasurementsIndex = 0;
|
||||
|
||||
node->layout.measuredDimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
@ -90,14 +84,103 @@ void CSSNodeInit(CSSNode* node) {
|
||||
node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode)-1;
|
||||
}
|
||||
|
||||
CSSNode* CSSNodeNew() {
|
||||
CSSNode* node = (CSSNode*)calloc(1, sizeof(*node));
|
||||
CSSNodeInit(node);
|
||||
return node;
|
||||
#define CSS_NODE_PROPERTY_IMPL(type, name, paramName, instanceName) \
|
||||
void CSSNodeSet##name(CSSNodeRef node, type paramName) { \
|
||||
node->instanceName = paramName;\
|
||||
} \
|
||||
\
|
||||
type CSSNodeGet##name(CSSNodeRef node) { \
|
||||
return node->instanceName;\
|
||||
} \
|
||||
|
||||
#define CSS_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \
|
||||
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName) { \
|
||||
node->style.instanceName = paramName;\
|
||||
} \
|
||||
\
|
||||
type CSSNodeStyleGet##name(CSSNodeRef node) { \
|
||||
return node->style.instanceName;\
|
||||
} \
|
||||
|
||||
#define CSS_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
|
||||
type CSSNodeLayoutGet##name(CSSNodeRef node) { \
|
||||
return node->layout.instanceName;\
|
||||
} \
|
||||
|
||||
CSS_NODE_PROPERTY_IMPL(void*, Context, context, context);
|
||||
CSS_NODE_PROPERTY_IMPL(int, ChildCount, childCount, childCount);
|
||||
CSS_NODE_PROPERTY_IMPL(CSSMeasureFunc, MeasureFunc, measureFunc, measure);
|
||||
CSS_NODE_PROPERTY_IMPL(CSSChildFunc, ChildFunc, childFunc, getChild);
|
||||
CSS_NODE_PROPERTY_IMPL(CSSIsDirtyFunc, IsDirtyFunc, isDirtyFunc, isDirty);
|
||||
CSS_NODE_PROPERTY_IMPL(CSSIsTextFunc, IsTextFunc, isTextFunc, isTextNode);
|
||||
CSS_NODE_PROPERTY_IMPL(CSSPrintFunc, PrintFunc, printFunc, print);
|
||||
CSS_NODE_PROPERTY_IMPL(bool, ShouldUpdate, shouldUpdate, shouldUpdate);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSDirection, Direction, direction, direction);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSFlexDirection, FlexDirection, flexDirection, flexDirection);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSJustify, JustifyContent, justifyContent, justifyContent);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignContent, alignContent, alignContent);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignItems, alignItems, alignItems);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignSelf, alignSelf, alignSelf);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSPositionType, PositionType, positionType, positionType);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSWrapType, FlexWrap, flexWrap, flexWrap);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(CSSOverflow, Overflow, overflow, overflow);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, Flex, flex, flex);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionLeft, positionLeft, position[CSSPositionLeft]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionTop, positionTop, position[CSSPositionTop]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionRight, positionRight, position[CSSPositionRight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionBottom, positionBottom, position[CSSPositionBottom]);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginLeft, marginLeft, margin[CSSPositionLeft]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginTop, marginTop, margin[CSSPositionTop]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginRight, marginRight, margin[CSSPositionRight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginBottom, marginBottom, margin[CSSPositionBottom]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginStart, marginStart, margin[CSSPositionStart]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginEnd, marginEnd, margin[CSSPositionEnd]);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingLeft, paddingLeft, padding[CSSPositionLeft]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingTop, paddingTop, padding[CSSPositionTop]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingRight, paddingRight, padding[CSSPositionRight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingBottom, paddingBottom, padding[CSSPositionBottom]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingStart, paddingStart, padding[CSSPositionStart]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingEnd, paddingEnd, padding[CSSPositionEnd]);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderLeft, borderLeft, border[CSSPositionLeft]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderTop, borderTop, border[CSSPositionTop]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderRight, borderRight, border[CSSPositionRight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderBottom, borderBottom, border[CSSPositionBottom]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderStart, borderStart, border[CSSPositionStart]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderEnd, BorderEnd, border[CSSPositionEnd]);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, Width, width, dimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, Height, height, dimensions[CSSDimensionHeight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MinWidth, minWidth, minDimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimensionHeight]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSPositionLeft]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSPositionTop]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSPositionRight]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Bottom, position[CSSPositionBottom]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[CSSDimensionHeight]);
|
||||
|
||||
int gCurrentGenerationCount = 0;
|
||||
|
||||
bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection,
|
||||
CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason);
|
||||
|
||||
bool isUndefined(float value) {
|
||||
return isnan(value);
|
||||
}
|
||||
|
||||
void CSSNodeFree(CSSNode* node) {
|
||||
free(node);
|
||||
static bool eq(float a, float b) {
|
||||
if (isUndefined(a)) {
|
||||
return isUndefined(b);
|
||||
}
|
||||
return fabs(a - b) < 0.0001;
|
||||
}
|
||||
|
||||
static void indent(int n) {
|
||||
@ -682,7 +765,7 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
|
||||
} else {
|
||||
|
||||
// Measure the text under the current constraints.
|
||||
CSSMeasureResult measureDim = node->measure(
|
||||
CSSSize measuredSize = node->measure(
|
||||
node->context,
|
||||
|
||||
innerWidth,
|
||||
@ -693,11 +776,11 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
|
||||
|
||||
node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow,
|
||||
(widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ?
|
||||
measureDim.dimensions[CSSDimensionWidth] + paddingAndBorderAxisRow :
|
||||
measuredSize.width + paddingAndBorderAxisRow :
|
||||
availableWidth - marginAxisRow);
|
||||
node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn,
|
||||
(heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ?
|
||||
measureDim.dimensions[CSSDimensionHeight] + paddingAndBorderAxisColumn :
|
||||
measuredSize.height + paddingAndBorderAxisColumn :
|
||||
availableHeight - marginAxisColumn);
|
||||
}
|
||||
|
||||
@ -1764,7 +1847,7 @@ bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeig
|
||||
if (performLayout) {
|
||||
node->layout.dimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth];
|
||||
node->layout.dimensions[CSSDimensionHeight] = node->layout.measuredDimensions[CSSDimensionHeight];
|
||||
layout->shouldUpdate = true;
|
||||
node->shouldUpdate = true;
|
||||
}
|
||||
|
||||
gDepth--;
|
||||
@ -1772,7 +1855,7 @@ bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeig
|
||||
return (needToVisitNode || cachedResults == NULL);
|
||||
}
|
||||
|
||||
void layoutNode(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) {
|
||||
void CSSNodeCalculateLayout(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) {
|
||||
// Increment the generation count. This will force the recursive routine to visit
|
||||
// all dirty nodes at least once. Subsequent visits will be skipped if the input
|
||||
// parameters don't change.
|
||||
|
@ -7,8 +7,8 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#ifndef __LAYOUT_H
|
||||
#define __LAYOUT_H
|
||||
#ifndef __CSS_LAYOUT_H
|
||||
#define __CSS_LAYOUT_H
|
||||
|
||||
#include <math.h>
|
||||
#ifndef __cplusplus
|
||||
@ -97,110 +97,110 @@ typedef enum CSSDimension {
|
||||
CSSDimensionHeight,
|
||||
} CSSDimension;
|
||||
|
||||
typedef struct CSSCachedMeasurement {
|
||||
float availableWidth;
|
||||
float availableHeight;
|
||||
CSSMeasureMode widthMeasureMode;
|
||||
CSSMeasureMode heightMeasureMode;
|
||||
|
||||
float computedWidth;
|
||||
float computedHeight;
|
||||
} CSSCachedMeasurement;
|
||||
|
||||
// This value was chosen based on empiracle data. Even the most complicated
|
||||
// layouts should not require more than 16 entries to fit within the cache.
|
||||
enum {
|
||||
CSS_MAX_CACHED_RESULT_COUNT = 16
|
||||
};
|
||||
|
||||
typedef struct CSSLayout {
|
||||
float position[4];
|
||||
float dimensions[2];
|
||||
CSSDirection direction;
|
||||
|
||||
float flexBasis;
|
||||
|
||||
// Instead of recomputing the entire layout every single time, we
|
||||
// cache some information to break early when nothing changed
|
||||
bool shouldUpdate;
|
||||
int generationCount;
|
||||
CSSDirection lastParentDirection;
|
||||
|
||||
int nextCachedMeasurementsIndex;
|
||||
CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
|
||||
float measuredDimensions[2];
|
||||
|
||||
CSSCachedMeasurement cached_layout;
|
||||
} CSSLayout;
|
||||
|
||||
typedef struct CSSMeasureResult {
|
||||
float dimensions[2];
|
||||
} CSSMeasureResult;
|
||||
|
||||
typedef struct CSSStyle {
|
||||
CSSDirection direction;
|
||||
CSSFlexDirection flexDirection;
|
||||
CSSJustify justifyContent;
|
||||
CSSAlign alignContent;
|
||||
CSSAlign alignItems;
|
||||
CSSAlign alignSelf;
|
||||
CSSPositionType positionType;
|
||||
CSSWrapType flexWrap;
|
||||
CSSOverflow overflow;
|
||||
float flex;
|
||||
float margin[6];
|
||||
float position[4];
|
||||
/**
|
||||
* You should skip all the rules that contain negative values for the
|
||||
* following attributes. For example:
|
||||
* {padding: 10, paddingLeft: -5}
|
||||
* should output:
|
||||
* {left: 10 ...}
|
||||
* the following two are incorrect:
|
||||
* {left: -5 ...}
|
||||
* {left: 0 ...}
|
||||
*/
|
||||
float padding[6];
|
||||
float border[6];
|
||||
float dimensions[2];
|
||||
float minDimensions[2];
|
||||
float maxDimensions[2];
|
||||
} CSSStyle;
|
||||
|
||||
typedef struct CSSNode {
|
||||
CSSStyle style;
|
||||
CSSLayout layout;
|
||||
int childCount;
|
||||
int lineIndex;
|
||||
|
||||
struct CSSNode* nextChild;
|
||||
|
||||
CSSMeasureResult (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
|
||||
void (*print)(void *context);
|
||||
struct CSSNode* (*getChild)(void *context, int i);
|
||||
bool (*isDirty)(void *context);
|
||||
bool (*isTextNode)(void *context);
|
||||
void *context;
|
||||
} CSSNode;
|
||||
|
||||
// Lifecycle of nodes and children
|
||||
CSSNode *CSSNodeNew();
|
||||
void CSSNodeInit(CSSNode *node);
|
||||
void CSSNodeFree(CSSNode *node);
|
||||
|
||||
// Print utilities
|
||||
typedef enum CSSPrintOptions {
|
||||
CSSPrintOptionsLayout = 1,
|
||||
CSSPrintOptionsStyle = 2,
|
||||
CSSPrintOptionsChildren = 4,
|
||||
} CSSPrintOptions;
|
||||
|
||||
void CSSNodePrint(CSSNode *node, CSSPrintOptions options);
|
||||
typedef struct CSSSize {
|
||||
float width;
|
||||
float height;
|
||||
} CSSSize;
|
||||
|
||||
typedef struct CSSNode * CSSNodeRef;
|
||||
typedef CSSSize (*CSSMeasureFunc)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode);
|
||||
typedef CSSNodeRef (*CSSChildFunc)(void *context, int i);
|
||||
typedef bool (*CSSIsDirtyFunc)(void *context);
|
||||
typedef bool (*CSSIsTextFunc)(void *context);
|
||||
typedef void (*CSSPrintFunc)(void *context);
|
||||
|
||||
// CSSNode
|
||||
CSSNodeRef CSSNodeNew();
|
||||
void CSSNodeInit(CSSNodeRef node);
|
||||
void CSSNodeFree(CSSNodeRef node);
|
||||
|
||||
void CSSNodeCalculateLayout(
|
||||
CSSNodeRef node,
|
||||
float availableWidth,
|
||||
float availableHeight,
|
||||
CSSDirection parentDirection);
|
||||
|
||||
void CSSNodePrint(CSSNodeRef node, CSSPrintOptions options);
|
||||
|
||||
// Function that computes the layout!
|
||||
void layoutNode(CSSNode *node, float availableWidth, float availableHeight, CSSDirection parentDirection);
|
||||
bool isUndefined(float value);
|
||||
|
||||
#define CSS_NODE_PROPERTY(type, name, paramName) \
|
||||
void CSSNodeSet##name(CSSNodeRef node, type paramName); \
|
||||
type CSSNodeGet##name(CSSNodeRef node);
|
||||
|
||||
#define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \
|
||||
void CSSNodeStyleSet##name(CSSNodeRef node, type paramName); \
|
||||
type CSSNodeStyleGet##name(CSSNodeRef node);
|
||||
|
||||
#define CSS_NODE_LAYOUT_PROPERTY(type, name) \
|
||||
type CSSNodeLayoutGet##name(CSSNodeRef node);
|
||||
|
||||
CSS_NODE_PROPERTY(void*, Context, context);
|
||||
CSS_NODE_PROPERTY(int, ChildCount, childCount);
|
||||
CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc);
|
||||
CSS_NODE_PROPERTY(CSSChildFunc, ChildFunc, childFunc);
|
||||
CSS_NODE_PROPERTY(CSSIsDirtyFunc, IsDirtyFunc, isDirtyFunc);
|
||||
CSS_NODE_PROPERTY(CSSIsTextFunc, IsTextFunc, isTextFunc);
|
||||
CSS_NODE_PROPERTY(CSSPrintFunc, PrintFunc, printFunc);
|
||||
CSS_NODE_PROPERTY(bool, ShouldUpdate, shouldUpdate);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(CSSDirection, Direction, direction);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSFlexDirection, FlexDirection, flexDirection);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSJustify, JustifyContent, justifyContent);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignContent, alignContent);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignItems, alignItems);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignSelf, alignSelf);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSPositionType, PositionType, positionType);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSWrapType, FlexWrap, flexWrap);
|
||||
CSS_NODE_STYLE_PROPERTY(CSSOverflow, Overflow, overflow);
|
||||
CSS_NODE_STYLE_PROPERTY(float, Flex, flex);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(float, PositionLeft, positionLeft);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PositionTop, positionTop);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PositionRight, positionRight);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PositionBottom, positionBottom);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginLeft, marginLeft);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginTop, marginTop);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginRight, marginRight);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginBottom, marginBottom);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginStart, marginStart);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MarginEnd, marginEnd);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingLeft, paddingLeft);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingTop, paddingTop);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingRight, paddingRight);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingBottom, paddingBottom);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingStart, paddingStart);
|
||||
CSS_NODE_STYLE_PROPERTY(float, PaddingEnd, paddingEnd);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderLeft, borderLeft);
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderTop, borderTop);
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderRight, borderRight);
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderBottom, borderBottom);
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderStart, borderStart);
|
||||
CSS_NODE_STYLE_PROPERTY(float, BorderEnd, borderEnd);
|
||||
|
||||
CSS_NODE_STYLE_PROPERTY(float, Width, width);
|
||||
CSS_NODE_STYLE_PROPERTY(float, Height, height);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MinWidth, minWidth);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Left);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Top);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Right);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Bottom);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Width);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Height);
|
||||
|
||||
CSS_EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
@ -121,6 +121,7 @@
|
||||
000E6CEA1AB0E980000CDF4D /* RCTSourceCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSourceCode.m; sourceTree = "<group>"; };
|
||||
008341F41D1DB34400876D9A /* RCTJSStackFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSStackFrame.m; sourceTree = "<group>"; };
|
||||
008341F51D1DB34400876D9A /* RCTJSStackFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTJSStackFrame.h; sourceTree = "<group>"; };
|
||||
131541CF1D3E4893006A0E08 /* CSSLayout-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSSLayout-internal.h"; sourceTree = "<group>"; };
|
||||
131B6AF01AF1093D00FFC3E0 /* RCTSegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControl.h; sourceTree = "<group>"; };
|
||||
131B6AF11AF1093D00FFC3E0 /* RCTSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSegmentedControl.m; sourceTree = "<group>"; };
|
||||
131B6AF21AF1093D00FFC3E0 /* RCTSegmentedControlManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSegmentedControlManager.h; sourceTree = "<group>"; };
|
||||
@ -342,6 +343,7 @@
|
||||
133683431D37ACA10077D0C3 /* CSSLayout */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
131541CF1D3E4893006A0E08 /* CSSLayout-internal.h */,
|
||||
133683441D37ACA10077D0C3 /* CSSLayout.c */,
|
||||
133683451D37ACA10077D0C3 /* CSSLayout.h */,
|
||||
133683481D37ACA10077D0C3 /* CSSMacros.h */,
|
||||
|
@ -21,7 +21,7 @@
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if ([[RCTI18nUtil sharedInstance] isRTL]) {
|
||||
self.cssNode->style.direction = CSSDirectionRTL;
|
||||
CSSNodeStyleSetDirection(self.cssNode, CSSDirectionRTL);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
@ -33,14 +33,14 @@
|
||||
case RCTRootViewSizeFlexibilityNone:
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityWidth:
|
||||
self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
CSSNodeStyleSetWidth(self.cssNode, CSSUndefined);
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityHeight:
|
||||
self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined;
|
||||
CSSNodeStyleSetHeight(self.cssNode, CSSUndefined);
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityWidthAndHeight:
|
||||
self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined;
|
||||
CSSNodeStyleSetWidth(self.cssNode, CSSUndefined);
|
||||
CSSNodeStyleSetHeight(self.cssNode, CSSUndefined);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
{
|
||||
[self applySizeConstraints];
|
||||
|
||||
layoutNode(self.cssNode, CSSUndefined, CSSUndefined, CSSDirectionInherit);
|
||||
CSSNodeCalculateLayout(self.cssNode, CSSUndefined, CSSUndefined, CSSDirectionInherit);
|
||||
|
||||
NSMutableSet<RCTShadowView *> *viewsWithNewFrame = [NSMutableSet set];
|
||||
[self applyLayoutNode:self.cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero];
|
||||
|
@ -44,7 +44,7 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
|
||||
- (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER;
|
||||
|
||||
@property (nonatomic, weak, readonly) RCTShadowView *superview;
|
||||
@property (nonatomic, assign, readonly) CSSNode *cssNode;
|
||||
@property (nonatomic, assign, readonly) CSSNodeRef cssNode;
|
||||
@property (nonatomic, copy) NSString *viewName;
|
||||
@property (nonatomic, strong) UIColor *backgroundColor; // Used to propagate to children
|
||||
@property (nonatomic, assign) RCTUpdateLifecycle layoutLifecycle;
|
||||
@ -172,14 +172,14 @@ typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry
|
||||
* is split into two methods so subclasses can override `applyLayoutToChildren:`
|
||||
* while using default implementation of `applyLayoutNode:`.
|
||||
*/
|
||||
- (void)applyLayoutNode:(CSSNode *)node
|
||||
- (void)applyLayoutNode:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Enumerate the child nodes and tell them to apply layout.
|
||||
*/
|
||||
- (void)applyLayoutToChildren:(CSSNode *)node
|
||||
- (void)applyLayoutToChildren:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition;
|
||||
|
||||
|
@ -56,7 +56,7 @@ static void RCTPrint(void *context)
|
||||
printf("%s(%zd), ", shadowView.viewName.UTF8String, shadowView.reactTag.integerValue);
|
||||
}
|
||||
|
||||
static CSSNode *RCTGetChild(void *context, int i)
|
||||
static CSSNodeRef RCTGetChild(void *context, int i)
|
||||
{
|
||||
RCTShadowView *shadowView = (__bridge RCTShadowView *)context;
|
||||
RCTShadowView *child = [shadowView reactSubviews][i];
|
||||
@ -70,25 +70,53 @@ static bool RCTIsDirty(void *context)
|
||||
}
|
||||
|
||||
// Enforces precedence rules, e.g. marginLeft > marginHorizontal > margin.
|
||||
static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float style[CSSPositionCount]) {
|
||||
style[CSSPositionLeft] = !isUndefined(metaProps[META_PROP_LEFT]) ? metaProps[META_PROP_LEFT]
|
||||
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL]
|
||||
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
|
||||
: 0;
|
||||
style[CSSPositionRight] = !isUndefined(metaProps[META_PROP_RIGHT]) ? metaProps[META_PROP_RIGHT]
|
||||
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL]
|
||||
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
|
||||
: 0;
|
||||
style[CSSPositionTop] = !isUndefined(metaProps[META_PROP_TOP]) ? metaProps[META_PROP_TOP]
|
||||
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL]
|
||||
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
|
||||
: 0;
|
||||
style[CSSPositionBottom] = !isUndefined(metaProps[META_PROP_BOTTOM]) ? metaProps[META_PROP_BOTTOM]
|
||||
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL]
|
||||
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
|
||||
: 0;
|
||||
#define DEFINE_PROCESS_META_PROPS(type) \
|
||||
static void RCTProcessMetaProps##type(const float metaProps[META_PROP_COUNT], CSSNodeRef node) { \
|
||||
if (!isUndefined(metaProps[META_PROP_LEFT])) { \
|
||||
CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_LEFT]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_HORIZONTAL])) { \
|
||||
CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_HORIZONTAL]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
|
||||
CSSNodeStyleSet##type##Left(node, metaProps[META_PROP_ALL]); \
|
||||
} else { \
|
||||
CSSNodeStyleSet##type##Left(node, 0); \
|
||||
} \
|
||||
\
|
||||
if (!isUndefined(metaProps[META_PROP_RIGHT])) { \
|
||||
CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_RIGHT]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_HORIZONTAL])) { \
|
||||
CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_HORIZONTAL]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
|
||||
CSSNodeStyleSet##type##Right(node, metaProps[META_PROP_ALL]); \
|
||||
} else { \
|
||||
CSSNodeStyleSet##type##Right(node, 0); \
|
||||
} \
|
||||
\
|
||||
if (!isUndefined(metaProps[META_PROP_TOP])) { \
|
||||
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_TOP]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_VERTICAL])) { \
|
||||
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_VERTICAL]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
|
||||
CSSNodeStyleSet##type##Top(node, metaProps[META_PROP_ALL]); \
|
||||
} else { \
|
||||
CSSNodeStyleSet##type##Top(node, 0); \
|
||||
} \
|
||||
\
|
||||
if (!isUndefined(metaProps[META_PROP_BOTTOM])) { \
|
||||
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_BOTTOM]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_VERTICAL])) { \
|
||||
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_VERTICAL]); \
|
||||
} else if (!isUndefined(metaProps[META_PROP_ALL])) { \
|
||||
CSSNodeStyleSet##type##Bottom(node, metaProps[META_PROP_ALL]); \
|
||||
} else { \
|
||||
CSSNodeStyleSet##type##Bottom(node, 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_PROCESS_META_PROPS(Padding);
|
||||
DEFINE_PROCESS_META_PROPS(Margin);
|
||||
DEFINE_PROCESS_META_PROPS(Border);
|
||||
|
||||
// The absolute stuff is so that we can take into account our absolute position when rounding in order to
|
||||
// snap to the pixel grid. For example, say you have the following structure:
|
||||
//
|
||||
@ -118,29 +146,29 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
// width = 213.5 - 106.5 = 107
|
||||
// You'll notice that this is the same width we calculated for the parent view because we've taken its position into account.
|
||||
|
||||
- (void)applyLayoutNode:(CSSNode *)node
|
||||
- (void)applyLayoutNode:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition
|
||||
{
|
||||
if (!node->layout.shouldUpdate) {
|
||||
if (!CSSNodeGetShouldUpdate(node)) {
|
||||
return;
|
||||
}
|
||||
node->layout.shouldUpdate = false;
|
||||
CSSNodeSetShouldUpdate(node, false);
|
||||
_layoutLifecycle = RCTUpdateLifecycleComputed;
|
||||
|
||||
CGPoint absoluteTopLeft = {
|
||||
absolutePosition.x + node->layout.position[CSSPositionLeft],
|
||||
absolutePosition.y + node->layout.position[CSSPositionTop]
|
||||
absolutePosition.x + CSSNodeLayoutGetLeft(node),
|
||||
absolutePosition.y + CSSNodeLayoutGetTop(node)
|
||||
};
|
||||
|
||||
CGPoint absoluteBottomRight = {
|
||||
absolutePosition.x + node->layout.position[CSSPositionLeft] + node->layout.dimensions[CSSDimensionWidth],
|
||||
absolutePosition.y + node->layout.position[CSSPositionTop] + node->layout.dimensions[CSSDimensionHeight]
|
||||
absolutePosition.x + CSSNodeLayoutGetLeft(node) + CSSNodeLayoutGetWidth(node),
|
||||
absolutePosition.y + CSSNodeLayoutGetTop(node) + CSSNodeLayoutGetHeight(node)
|
||||
};
|
||||
|
||||
CGRect frame = {{
|
||||
RCTRoundPixelValue(node->layout.position[CSSPositionLeft]),
|
||||
RCTRoundPixelValue(node->layout.position[CSSPositionTop]),
|
||||
RCTRoundPixelValue(CSSNodeLayoutGetLeft(node)),
|
||||
RCTRoundPixelValue(CSSNodeLayoutGetTop(node)),
|
||||
}, {
|
||||
RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x),
|
||||
RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y)
|
||||
@ -151,19 +179,19 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
[viewsWithNewFrame addObject:self];
|
||||
}
|
||||
|
||||
absolutePosition.x += node->layout.position[CSSPositionLeft];
|
||||
absolutePosition.y += node->layout.position[CSSPositionTop];
|
||||
absolutePosition.x += CSSNodeLayoutGetLeft(node);
|
||||
absolutePosition.y += CSSNodeLayoutGetTop(node);
|
||||
|
||||
[self applyLayoutToChildren:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
|
||||
}
|
||||
|
||||
- (void)applyLayoutToChildren:(CSSNode *)node
|
||||
- (void)applyLayoutToChildren:(CSSNodeRef)node
|
||||
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
|
||||
absolutePosition:(CGPoint)absolutePosition
|
||||
{
|
||||
for (int i = 0; i < node->childCount; ++i) {
|
||||
for (int i = 0; i < CSSNodeGetChildCount(node); ++i) {
|
||||
RCTShadowView *child = (RCTShadowView *)_reactSubviews[i];
|
||||
[child applyLayoutNode:node->getChild(node->context, i)
|
||||
[child applyLayoutNode:RCTGetChild(CSSNodeGetContext(node), i)
|
||||
viewsWithNewFrame:viewsWithNewFrame
|
||||
absolutePosition:absolutePosition];
|
||||
}
|
||||
@ -237,18 +265,19 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
}
|
||||
|
||||
if (!CGRectEqualToRect(frame, _frame)) {
|
||||
_cssNode->style.positionType = CSSPositionTypeAbsolute;
|
||||
_cssNode->style.dimensions[CSSDimensionWidth] = frame.size.width;
|
||||
_cssNode->style.dimensions[CSSDimensionHeight] = frame.size.height;
|
||||
_cssNode->style.position[CSSPositionLeft] = frame.origin.x;
|
||||
_cssNode->style.position[CSSPositionTop] = frame.origin.y;
|
||||
CSSNodeStyleSetPositionType(_cssNode, CSSPositionTypeAbsolute);
|
||||
CSSNodeStyleSetWidth(_cssNode, frame.size.width);
|
||||
CSSNodeStyleSetHeight(_cssNode, frame.size.height);
|
||||
CSSNodeStyleSetPositionLeft(_cssNode, frame.origin.x);
|
||||
CSSNodeStyleSetPositionTop(_cssNode, frame.origin.y);
|
||||
|
||||
// Our parent has asked us to change our cssNode->styles. Dirty the layout
|
||||
// so that we can rerun layout on this node. The request came from our parent
|
||||
// so there's no need to dirty our ancestors by calling dirtyLayout.
|
||||
_layoutLifecycle = RCTUpdateLifecycleDirtied;
|
||||
}
|
||||
|
||||
layoutNode(_cssNode, frame.size.width, frame.size.height, CSSDirectionInherit);
|
||||
CSSNodeCalculateLayout(_cssNode, frame.size.width, frame.size.height, CSSDirectionInherit);
|
||||
[self applyLayoutNode:_cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
|
||||
}
|
||||
|
||||
@ -289,10 +318,10 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
_reactSubviews = [NSMutableArray array];
|
||||
|
||||
_cssNode = CSSNodeNew();
|
||||
_cssNode->context = (__bridge void *)self;
|
||||
_cssNode->print = RCTPrint;
|
||||
_cssNode->getChild = RCTGetChild;
|
||||
_cssNode->isDirty = RCTIsDirty;
|
||||
CSSNodeSetContext(_cssNode, (__bridge void *)self);
|
||||
CSSNodeSetChildFunc(_cssNode, RCTGetChild);
|
||||
CSSNodeSetPrintFunc(_cssNode, RCTPrint);
|
||||
CSSNodeSetIsDirtyFunc(_cssNode, RCTIsDirty);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -359,7 +388,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[_reactSubviews insertObject:subview atIndex:atIndex];
|
||||
_cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count;
|
||||
CSSNodeSetChildCount(_cssNode, [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count);
|
||||
subview->_superview = self;
|
||||
_didUpdateSubviews = YES;
|
||||
[self dirtyText];
|
||||
@ -375,7 +404,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
||||
_didUpdateSubviews = YES;
|
||||
subview->_superview = nil;
|
||||
[_reactSubviews removeObject:subview];
|
||||
_cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count;
|
||||
CSSNodeSetChildCount(_cssNode, [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count);
|
||||
}
|
||||
|
||||
- (NSArray<RCTShadowView *> *)reactSubviews
|
||||
@ -475,10 +504,10 @@ RCT_PADDING_PROPERTY(Right, RIGHT)
|
||||
- (UIEdgeInsets)paddingAsInsets
|
||||
{
|
||||
return (UIEdgeInsets){
|
||||
_cssNode->style.padding[CSSPositionTop],
|
||||
_cssNode->style.padding[CSSPositionLeft],
|
||||
_cssNode->style.padding[CSSPositionBottom],
|
||||
_cssNode->style.padding[CSSPositionRight]
|
||||
CSSNodeStyleGetPaddingTop(_cssNode),
|
||||
CSSNodeStyleGetPaddingLeft(_cssNode),
|
||||
CSSNodeStyleGetPaddingBottom(_cssNode),
|
||||
CSSNodeStyleGetPaddingRight(_cssNode)
|
||||
};
|
||||
}
|
||||
|
||||
@ -504,58 +533,66 @@ RCT_BORDER_PROPERTY(Right, RIGHT)
|
||||
// Dimensions
|
||||
|
||||
|
||||
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, category) \
|
||||
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
|
||||
- (void)set##setProp:(CGFloat)value \
|
||||
{ \
|
||||
_cssNode->style.category[CSS##cssProp] = value; \
|
||||
CSSNodeStyleSet##cssProp(_cssNode, value); \
|
||||
[self dirtyLayout]; \
|
||||
[self dirtyText]; \
|
||||
} \
|
||||
- (CGFloat)getProp \
|
||||
{ \
|
||||
return _cssNode->style.category[CSS##cssProp]; \
|
||||
return CSSNodeStyleGet##cssProp(_cssNode); \
|
||||
}
|
||||
|
||||
RCT_DIMENSION_PROPERTY(Width, width, DimensionWidth, dimensions)
|
||||
RCT_DIMENSION_PROPERTY(Height, height, DimensionHeight, dimensions)
|
||||
|
||||
RCT_DIMENSION_PROPERTY(MinWidth, minWidth, DimensionWidth, minDimensions)
|
||||
RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, DimensionWidth, maxDimensions)
|
||||
RCT_DIMENSION_PROPERTY(MinHeight, minHeight, DimensionHeight, minDimensions)
|
||||
RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, DimensionHeight, maxDimensions)
|
||||
RCT_DIMENSION_PROPERTY(Width, width, Width)
|
||||
RCT_DIMENSION_PROPERTY(Height, height, Height)
|
||||
RCT_DIMENSION_PROPERTY(MinWidth, minWidth, MinWidth)
|
||||
RCT_DIMENSION_PROPERTY(MinHeight, minHeight, MinHeight)
|
||||
RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, MaxWidth)
|
||||
RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, MaxHeight)
|
||||
|
||||
// Position
|
||||
|
||||
#define RCT_POSITION_PROPERTY(setProp, getProp, cssProp) \
|
||||
RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, position)
|
||||
|
||||
RCT_POSITION_PROPERTY(Top, top, PositionTop)
|
||||
RCT_POSITION_PROPERTY(Right, right, PositionRight)
|
||||
RCT_POSITION_PROPERTY(Bottom, bottom, PositionBottom)
|
||||
RCT_POSITION_PROPERTY(Left, left, PositionLeft)
|
||||
RCT_DIMENSION_PROPERTY(Top, top, PositionTop)
|
||||
RCT_DIMENSION_PROPERTY(Right, right, PositionRight)
|
||||
RCT_DIMENSION_PROPERTY(Bottom, bottom, PositionBottom)
|
||||
RCT_DIMENSION_PROPERTY(Left, left, PositionLeft)
|
||||
|
||||
- (void)setFrame:(CGRect)frame
|
||||
{
|
||||
_cssNode->style.position[CSSPositionLeft] = CGRectGetMinX(frame);
|
||||
_cssNode->style.position[CSSPositionTop] = CGRectGetMinY(frame);
|
||||
_cssNode->style.dimensions[CSSDimensionWidth] = CGRectGetWidth(frame);
|
||||
_cssNode->style.dimensions[CSSDimensionHeight] = CGRectGetHeight(frame);
|
||||
CSSNodeStyleSetPositionLeft(_cssNode, CGRectGetMinX(frame));
|
||||
CSSNodeStyleSetPositionTop(_cssNode, CGRectGetMinY(frame));
|
||||
CSSNodeStyleSetWidth(_cssNode, CGRectGetWidth(frame));
|
||||
CSSNodeStyleSetHeight(_cssNode, CGRectGetHeight(frame));
|
||||
[self dirtyLayout];
|
||||
}
|
||||
|
||||
static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension, CGFloat amount)
|
||||
static inline BOOL RCTAssignSuggestedDimension(CSSNodeRef cssNode, CSSDimension dimension, CGFloat amount)
|
||||
{
|
||||
if (amount != UIViewNoIntrinsicMetric
|
||||
&& isnan(cssNode->style.dimensions[dimension])) {
|
||||
cssNode->style.dimensions[dimension] = amount;
|
||||
return YES;
|
||||
if (amount != UIViewNoIntrinsicMetric) {
|
||||
switch (dimension) {
|
||||
case CSSDimensionWidth:
|
||||
if (isnan(CSSNodeStyleGetWidth(cssNode))) {
|
||||
CSSNodeStyleSetWidth(cssNode, amount);
|
||||
return YES;
|
||||
}
|
||||
break;
|
||||
case CSSDimensionHeight:
|
||||
if (isnan(CSSNodeStyleGetHeight(cssNode))) {
|
||||
CSSNodeStyleSetHeight(cssNode, amount);
|
||||
return YES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setIntrinsicContentSize:(CGSize)size
|
||||
{
|
||||
if (_cssNode->style.flex == 0) {
|
||||
if (CSSNodeStyleGetFlex(_cssNode) == 0) {
|
||||
BOOL dirty = NO;
|
||||
dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionHeight, size.height);
|
||||
dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionWidth, size.width);
|
||||
@ -567,15 +604,15 @@ static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension,
|
||||
|
||||
- (void)setTopLeft:(CGPoint)topLeft
|
||||
{
|
||||
_cssNode->style.position[CSSPositionLeft] = topLeft.x;
|
||||
_cssNode->style.position[CSSPositionTop] = topLeft.y;
|
||||
CSSNodeStyleSetPositionLeft(_cssNode, topLeft.x);
|
||||
CSSNodeStyleSetPositionTop(_cssNode, topLeft.y);
|
||||
[self dirtyLayout];
|
||||
}
|
||||
|
||||
- (void)setSize:(CGSize)size
|
||||
{
|
||||
_cssNode->style.dimensions[CSSDimensionWidth] = size.width;
|
||||
_cssNode->style.dimensions[CSSDimensionHeight] = size.height;
|
||||
CSSNodeStyleSetWidth(_cssNode, size.width);
|
||||
CSSNodeStyleSetHeight(_cssNode, size.height);
|
||||
[self dirtyLayout];
|
||||
}
|
||||
|
||||
@ -584,21 +621,21 @@ static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension,
|
||||
#define RCT_STYLE_PROPERTY(setProp, getProp, cssProp, type) \
|
||||
- (void)set##setProp:(type)value \
|
||||
{ \
|
||||
_cssNode->style.cssProp = value; \
|
||||
CSSNodeStyleSet##cssProp(_cssNode, value); \
|
||||
[self dirtyLayout]; \
|
||||
} \
|
||||
- (type)getProp \
|
||||
{ \
|
||||
return _cssNode->style.cssProp; \
|
||||
return CSSNodeStyleGet##cssProp(_cssNode); \
|
||||
}
|
||||
|
||||
RCT_STYLE_PROPERTY(Flex, flex, flex, CGFloat)
|
||||
RCT_STYLE_PROPERTY(FlexDirection, flexDirection, flexDirection, CSSFlexDirection)
|
||||
RCT_STYLE_PROPERTY(JustifyContent, justifyContent, justifyContent, CSSJustify)
|
||||
RCT_STYLE_PROPERTY(AlignSelf, alignSelf, alignSelf, CSSAlign)
|
||||
RCT_STYLE_PROPERTY(AlignItems, alignItems, alignItems, CSSAlign)
|
||||
RCT_STYLE_PROPERTY(Position, position, positionType, CSSPositionType)
|
||||
RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flexWrap, CSSWrapType)
|
||||
RCT_STYLE_PROPERTY(Flex, flex, Flex, CGFloat)
|
||||
RCT_STYLE_PROPERTY(FlexDirection, flexDirection, FlexDirection, CSSFlexDirection)
|
||||
RCT_STYLE_PROPERTY(JustifyContent, justifyContent, JustifyContent, CSSJustify)
|
||||
RCT_STYLE_PROPERTY(AlignSelf, alignSelf, AlignSelf, CSSAlign)
|
||||
RCT_STYLE_PROPERTY(AlignItems, alignItems, AlignItems, CSSAlign)
|
||||
RCT_STYLE_PROPERTY(Position, position, PositionType, CSSPositionType)
|
||||
RCT_STYLE_PROPERTY(FlexWrap, flexWrap, FlexWrap, CSSWrapType)
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)color
|
||||
{
|
||||
@ -624,13 +661,13 @@ RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flexWrap, CSSWrapType)
|
||||
- (void)didSetProps:(__unused NSArray<NSString *> *)changedProps
|
||||
{
|
||||
if (_recomputePadding) {
|
||||
RCTProcessMetaProps(_paddingMetaProps, _cssNode->style.padding);
|
||||
RCTProcessMetaPropsPadding(_paddingMetaProps, _cssNode);
|
||||
}
|
||||
if (_recomputeMargin) {
|
||||
RCTProcessMetaProps(_marginMetaProps, _cssNode->style.margin);
|
||||
RCTProcessMetaPropsMargin(_marginMetaProps, _cssNode);
|
||||
}
|
||||
if (_recomputeBorder) {
|
||||
RCTProcessMetaProps(_borderMetaProps, _cssNode->style.border);
|
||||
RCTProcessMetaPropsBorder(_borderMetaProps, _cssNode);
|
||||
}
|
||||
if (_recomputePadding || _recomputeMargin || _recomputeBorder) {
|
||||
[self dirtyLayout];
|
||||
|
Loading…
x
Reference in New Issue
Block a user