Skip to content

Commit

Permalink
[Yoga Beta] Improvements to the experimental support for Yoga layout.
Browse files Browse the repository at this point in the history
Yoga remains an unsupported / speculative feature, but these improvements are important for
the functionality of clients that are experimenting with it.

For example, without these changes, ASButtonNode is not able to lay out correctly. These
changes allow certain subtrees that use layout specs to coexist properly in a Yoga heirarchy.

The most significant change here is moving ASEdgeInsets into the #if YOGA gating. Although
this is technically an API change, this type was added with no known use cases and is
really only useful for flexbox layout specification. So, before usages of it are created,
it makes sense to constrain the Texture API surface until that time.
  • Loading branch information
appleguy committed Apr 23, 2017
1 parent e45c686 commit 605e369
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 30 deletions.
3 changes: 2 additions & 1 deletion Source/ASDisplayNode+Beta.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ extern void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable

@interface ASLayoutElementStyle (Yoga)

@property (nonatomic, assign, readwrite) ASStackLayoutDirection direction;
@property (nonatomic, assign, readwrite) ASStackLayoutDirection flexDirection;
@property (nonatomic, assign, readwrite) YGDirection direction;
@property (nonatomic, assign, readwrite) CGFloat spacing;
@property (nonatomic, assign, readwrite) ASStackLayoutJustifyContent justifyContent;
@property (nonatomic, assign, readwrite) ASStackLayoutAlignItems alignItems;
Expand Down
31 changes: 20 additions & 11 deletions Source/ASDisplayNode+Yoga.mm
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,15 @@ float yogaDimensionToPercent(ASDimension dimension)
ASDimension dimensionForEdgeWithEdgeInsets(YGEdge edge, ASEdgeInsets insets)
{
switch (edge) {
case YGEdgeLeft: return insets.left;
case YGEdgeTop: return insets.top;
case YGEdgeRight: return insets.right;
case YGEdgeBottom: return insets.bottom;
case YGEdgeLeft: return insets.left;
case YGEdgeTop: return insets.top;
case YGEdgeRight: return insets.right;
case YGEdgeBottom: return insets.bottom;
case YGEdgeStart: return insets.start;
case YGEdgeEnd: return insets.end;
case YGEdgeHorizontal: return insets.horizontal;
case YGEdgeVertical: return insets.vertical;
case YGEdgeAll: return insets.all;
default: ASDisplayNodeCAssert(NO, @"YGEdge other than ASEdgeInsets is not supported.");
return ASDimensionAuto;
}
Expand Down Expand Up @@ -305,10 +310,9 @@ - (void)setupYogaCalculatedLayout

- (void)setYogaMeasureFuncIfNeeded
{
// Manual size calculation via calculateSizeThatFits:
// This will be used for ASTextNode, as well as any other leaf node that has no layout spec.
if ((self.methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) == NO
&& self.layoutSpecBlock == NULL && self.yogaChildren.count == 0) {
// Size calculation via calculateSizeThatFits: or layoutSpecThatFits:
// This will be used for ASTextNode, as well as any other node that has no Yoga children
if (self.yogaChildren.count == 0) {
YGNodeRef yogaNode = self.yogaNode; // Use property to assign Ref if needed.
YGNodeSetContext(yogaNode, (__bridge void *)self);
YGNodeSetMeasureFunc(yogaNode, &ASLayoutElementYogaMeasureFunc);
Expand All @@ -326,6 +330,12 @@ - (void)invalidateCalculatedYogaLayout

- (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize
{
if (self.yogaParent) {
if (ASHierarchyStateIncludesYogaLayoutMeasuring(self.hierarchyState) == NO) {
[self setNeedsLayoutFromAbove];
}
return;
}
if (ASHierarchyStateIncludesYogaLayoutMeasuring(self.hierarchyState)) {
ASDisplayNodeAssert(NO, @"A Yoga layout is being performed by a parent; children must not perform their own until it is done! %@", [self displayNodeRecursiveDescription]);
return;
Expand Down Expand Up @@ -369,12 +379,12 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize
ASEdgeInsets border = style.border;

YGEdge edge = YGEdgeLeft;
for (int i = 0; i < 4; i++) {
for (int i = 0; i < YGEdgeAll + 1; i++) {
YGNODE_STYLE_SET_DIMENSION_WITH_EDGE(yogaNode, Position, dimensionForEdgeWithEdgeInsets(edge, position), edge);
YGNODE_STYLE_SET_DIMENSION_WITH_EDGE(yogaNode, Margin, dimensionForEdgeWithEdgeInsets(edge, margin), edge);
YGNODE_STYLE_SET_DIMENSION_WITH_EDGE(yogaNode, Padding, dimensionForEdgeWithEdgeInsets(edge, padding), edge);
YGNODE_STYLE_SET_FLOAT_WITH_EDGE(yogaNode, Border, dimensionForEdgeWithEdgeInsets(edge, border), edge);
edge = (edge == YGEdgeLeft ? YGEdgeTop : (edge == YGEdgeTop ? YGEdgeRight : YGEdgeBottom));
edge = (YGEdge)(edge + 1);
}

CGFloat aspectRatio = style.aspectRatio;
Expand All @@ -397,7 +407,6 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize
[node setYogaMeasureFuncIfNeeded];

/* TODO(appleguy): STYLE SETTER METHODS LEFT TO IMPLEMENT
void YGNodeStyleSetFlexDirection(YGNodeRef node, YGFlexDirection flexDirection);
void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow);
void YGNodeStyleSetFlex(YGNodeRef node, float flex);
*/
Expand Down
31 changes: 20 additions & 11 deletions Source/Layout/ASDimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,6 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT NSString *NSStringFromASLayoutSize(AS
NSStringFromASDimension(size.height)];
}

#pragma mark - ASEdgeInsets

typedef struct {
ASDimension top;
ASDimension left;
ASDimension bottom;
ASDimension right;
} ASEdgeInsets;

extern ASEdgeInsets const ASEdgeInsetsZero;

#pragma mark - ASSizeRange

/**
Expand Down Expand Up @@ -301,5 +290,25 @@ ASDISPLAYNODE_INLINE AS_WARN_UNUSED_RESULT BOOL ASSizeRangeEqualToSizeRange(ASSi
*/
extern AS_WARN_UNUSED_RESULT NSString *NSStringFromASSizeRange(ASSizeRange sizeRange);

#if YOGA

#pragma mark - ASEdgeInsets

typedef struct {
ASDimension top;
ASDimension left;
ASDimension bottom;
ASDimension right;
ASDimension start;
ASDimension end;
ASDimension horizontal;
ASDimension vertical;
ASDimension all;
} ASEdgeInsets;

extern ASEdgeInsets const ASEdgeInsetsZero;

#endif

NS_ASSUME_NONNULL_END
ASDISPLAYNODE_EXTERN_C_END
9 changes: 5 additions & 4 deletions Source/Layout/ASDimension.mm
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ ASOVERLOADABLE ASDimension ASDimensionMake(NSString *dimension)

ASLayoutSize const ASLayoutSizeAuto = {ASDimensionAuto, ASDimensionAuto};

#pragma mark - ASEdgeInsets

ASEdgeInsets const ASEdgeInsetsZero = {};

#pragma mark - ASSizeRange

ASSizeRange const ASSizeRangeZero = {};
Expand Down Expand Up @@ -108,3 +104,8 @@ ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRan
NSStringFromCGSize(sizeRange.min),
NSStringFromCGSize(sizeRange.max)];
}

#if YOGA
#pragma mark - Yoga - ASEdgeInsets
ASEdgeInsets const ASEdgeInsetsZero = {};
#endif
9 changes: 6 additions & 3 deletions Source/Layout/ASLayoutElement.mm
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ @implementation ASLayoutElementStyle {
std::atomic<CGPoint> _layoutPosition;

#if YOGA
std::atomic<ASStackLayoutDirection> _direction;
std::atomic<ASStackLayoutDirection> _flexDirection;
std::atomic<YGDirection> _direction;
std::atomic<CGFloat> _spacing;
std::atomic<ASStackLayoutJustifyContent> _justifyContent;
std::atomic<ASStackLayoutAlignItems> _alignItems;
Expand Down Expand Up @@ -595,7 +596,8 @@ - (NSString *)description

#if YOGA

- (ASStackLayoutDirection)direction { return _direction.load(); }
- (ASStackLayoutDirection)flexDirection { return _flexDirection.load(); }
- (YGDirection)direction { return _direction.load(); }
- (CGFloat)spacing { return _spacing.load(); }
- (ASStackLayoutJustifyContent)justifyContent { return _justifyContent.load(); }
- (ASStackLayoutAlignItems)alignItems { return _alignItems.load(); }
Expand All @@ -607,7 +609,8 @@ - (ASEdgeInsets)border { return _border.load(); }
- (CGFloat)aspectRatio { return _aspectRatio.load(); }
- (YGWrap)flexWrap { return _flexWrap.load(); }

- (void)setDirection:(ASStackLayoutDirection)direction { _direction.store(direction); }
- (void)setFlexDirection:(ASStackLayoutDirection)flexDirection { _flexDirection.store(flexDirection); }
- (void)setDirection:(YGDirection)direction { _direction.store(direction); }
- (void)setSpacing:(CGFloat)spacing { _spacing.store(spacing); }
- (void)setJustifyContent:(ASStackLayoutJustifyContent)justify { _justifyContent.store(justify); }
- (void)setAlignItems:(ASStackLayoutAlignItems)alignItems { _alignItems.store(alignItems); }
Expand Down

0 comments on commit 605e369

Please sign in to comment.