This commit is contained in:
ricky cancro 2015-08-19 16:59:23 -07:00
parent 11896904a2
commit 774d91653b
16 changed files with 172 additions and 134 deletions

View File

@ -217,6 +217,8 @@
509E68651B3AEDC5009B9150 /* CGRect+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */; }; 509E68651B3AEDC5009B9150 /* CGRect+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */; };
509E68661B3AEDD7009B9150 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; }; 509E68661B3AEDD7009B9150 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; };
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; }; 9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; };
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -556,6 +558,7 @@
4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMultidimensionalArrayUtils.h; sourceTree = "<group>"; }; 4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMultidimensionalArrayUtils.h; sourceTree = "<group>"; };
4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultidimensionalArrayUtils.mm; sourceTree = "<group>"; }; 4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultidimensionalArrayUtils.mm; sourceTree = "<group>"; };
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; };
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = "<group>"; };
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; }; 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; };
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; }; AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; };
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; }; AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
@ -958,6 +961,7 @@
ACF6ED131B17843500DA7C62 /* ASOverlayLayoutSpec.mm */, ACF6ED131B17843500DA7C62 /* ASOverlayLayoutSpec.mm */,
ACF6ED141B17843500DA7C62 /* ASRatioLayoutSpec.h */, ACF6ED141B17843500DA7C62 /* ASRatioLayoutSpec.h */,
ACF6ED151B17843500DA7C62 /* ASRatioLayoutSpec.mm */, ACF6ED151B17843500DA7C62 /* ASRatioLayoutSpec.mm */,
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */,
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */, AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */,
ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */, ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */,
ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */, ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */,
@ -1004,6 +1008,7 @@
files = ( files = (
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */, AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */,
AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */, AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */,
9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */,
ACF6ED511B17847A00DA7C62 /* ASStackUnpositionedLayout.h in Headers */, ACF6ED511B17847A00DA7C62 /* ASStackUnpositionedLayout.h in Headers */,
ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutSpec.h in Headers */, ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutSpec.h in Headers */,
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */, ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
@ -1170,6 +1175,7 @@
B350620C1B010EFD0018CF92 /* ASTableViewProtocols.h in Headers */, B350620C1B010EFD0018CF92 /* ASTableViewProtocols.h in Headers */,
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */, B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */,
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */, B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */,
34EFC7731B701D0700AD841F /* ASStaticLayoutSpec.h in Headers */, 34EFC7731B701D0700AD841F /* ASStaticLayoutSpec.h in Headers */,
B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */, B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */,
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */, B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,

View File

@ -13,7 +13,7 @@
#import <AsyncDisplayKit/ASDealloc2MainObject.h> #import <AsyncDisplayKit/ASDealloc2MainObject.h>
#import <AsyncDisplayKit/ASDimension.h> #import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASLayoutable.h> #import <AsyncDisplayKit/ASStackLayoutable.h>
/** /**
* UIView creation block. Used to create the backing view of a new display node. * UIView creation block. Used to create the backing view of a new display node.
@ -40,7 +40,7 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
* *
*/ */
@interface ASDisplayNode : ASDealloc2MainObject <ASLayoutable> @interface ASDisplayNode : ASDealloc2MainObject <ASStackLayoutable>
/** @name Initializing a node object */ /** @name Initializing a node object */

View File

@ -48,8 +48,6 @@
@synthesize flexBasis = _flexBasis; @synthesize flexBasis = _flexBasis;
@synthesize alignSelf = _alignSelf; @synthesize alignSelf = _alignSelf;
@synthesize preferredFrameSize = _preferredFrameSize; @synthesize preferredFrameSize = _preferredFrameSize;
@synthesize ascender = _ascender;
@synthesize descender = _descender;
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector) BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
{ {
@ -159,8 +157,6 @@ void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)
_flexBasis = ASRelativeDimensionUnconstrained; _flexBasis = ASRelativeDimensionUnconstrained;
_preferredFrameSize = CGSizeZero; _preferredFrameSize = CGSizeZero;
_ascender = 0;
_descender = 0;
} }
- (id)init - (id)init
@ -457,6 +453,11 @@ void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)
#pragma mark - #pragma mark -
- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType
{
return 0;
}
- (CGSize)measure:(CGSize)constrainedSize - (CGSize)measure:(CGSize)constrainedSize
{ {
return [self measureWithSizeRange:ASSizeRangeMake(CGSizeZero, constrainedSize)].size; return [self measureWithSizeRange:ASSizeRangeMake(CGSizeZero, constrainedSize)].size;

View File

@ -17,6 +17,7 @@
#import <AsyncDisplayKit/ASTextNodeTextKitHelpers.h> #import <AsyncDisplayKit/ASTextNodeTextKitHelpers.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h> #import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import "ASInternalHelpers.h"
#import "ASTextNodeRenderer.h" #import "ASTextNodeRenderer.h"
#import "ASTextNodeShadower.h" #import "ASTextNodeShadower.h"
@ -105,6 +106,9 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
ASTextNodeShadower *_shadower; ASTextNodeShadower *_shadower;
UILongPressGestureRecognizer *_longPressGestureRecognizer; UILongPressGestureRecognizer *_longPressGestureRecognizer;
CGFloat _topBaseline;
CGFloat _bottomBaseline;
} }
#pragma mark - NSObject #pragma mark - NSObject
@ -356,8 +360,24 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
} }
}); });
self.ascender = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * [UIScreen mainScreen].scale)/[UIScreen mainScreen].scale; _topBaseline = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * ASScreenScale())/ASScreenScale();
self.descender = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * [UIScreen mainScreen].scale)/[UIScreen mainScreen].scale; _bottomBaseline = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * ASScreenScale())/ASScreenScale();
}
#pragma mark - Baseline computation
- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType
{
switch (baselineAlignmentType) {
case ASStackLayoutAlignItemsLastBaseline:
return self.calculatedSize.height + _bottomBaseline;
case ASStackLayoutAlignItemsFirstBaseline:
return _topBaseline;
default:
return 0;
}
} }
#pragma mark - Text Layout #pragma mark - Text Layout

View File

@ -8,9 +8,9 @@
* *
*/ */
#import <AsyncDisplayKit/ASLayoutable.h> #import <AsyncDisplayKit/ASStackLayoutable.h>
/** A layout spec is an immutable object that describes a layout, loosely inspired by React. */ /** A layout spec is an immutable object that describes a layout, loosely inspired by React. */
@interface ASLayoutSpec : NSObject <ASLayoutable> @interface ASLayoutSpec : NSObject <ASStackLayoutable>
@end @end

View File

@ -24,8 +24,6 @@
@synthesize flexShrink = _flexShrink; @synthesize flexShrink = _flexShrink;
@synthesize flexBasis = _flexBasis; @synthesize flexBasis = _flexBasis;
@synthesize alignSelf = _alignSelf; @synthesize alignSelf = _alignSelf;
@synthesize ascender = _ascender;
@synthesize descender = _descender;
+ (instancetype)new + (instancetype)new
{ {
@ -36,6 +34,11 @@
return spec; return spec;
} }
- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType
{
return 0;
}
#pragma mark - Layout #pragma mark - Layout
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize

View File

@ -20,53 +20,6 @@
*/ */
@protocol ASLayoutable <NSObject> @protocol ASLayoutable <NSObject>
/**
* @abstract Additional space to place before this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingBefore;
/**
* @abstract Additional space to place after this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingAfter;
/**
* @abstract If the sum of childrens' stack dimensions is less than the minimum size, should this object grow?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexGrow;
/**
* @abstract If the sum of childrens' stack dimensions is greater than the maximum size, should this object shrink?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexShrink;
/**
* @abstract Specifies the initial size in the stack dimension for this object.
* Default to ASRelativeDimensionUnconstrained.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
/**
* @abstract Orientation of the object along cross axis, overriding alignItems
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
/**
* @abstract Used for baseline alignment. The distance from the top of the object to its baseline.
*/
@property (nonatomic, readwrite) CGFloat ascender;
/**
* @abstract Used for baseline alignment. The distance from the baseline of the object to its bottom.
*/
@property (nonatomic, readwrite) CGFloat descender;
/** /**
* @abstract Calculate a layout based on given size range. * @abstract Calculate a layout based on given size range.
* *

View File

@ -8,6 +8,49 @@
* *
*/ */
/** The direction children are stacked in */
typedef NS_ENUM(NSUInteger, ASStackLayoutDirection) {
/** Children are stacked vertically */
ASStackLayoutDirectionVertical,
/** Children are stacked horizontally */
ASStackLayoutDirectionHorizontal,
};
/** If no children are flexible, how should this spec justify its children in the available space? */
typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) {
/**
On overflow, children overflow out of this spec's bounds on the right/bottom side.
On underflow, children are left/top-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentStart,
/**
On overflow, children are centered and overflow on both sides.
On underflow, children are centered within this spec's bounds in the stacking direction.
*/
ASStackLayoutJustifyContentCenter,
/**
On overflow, children overflow out of this spec's bounds on the left/top side.
On underflow, children are right/bottom-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentEnd,
};
/** Orientation of children along cross axis */
typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) {
/** Align children to start of cross axis */
ASStackLayoutAlignItemsStart,
/** Align children with end of cross axis */
ASStackLayoutAlignItemsEnd,
/** Center children on cross axis */
ASStackLayoutAlignItemsCenter,
/** Expand children to fill cross axis */
ASStackLayoutAlignItemsStretch,
/** Children align along the first baseline of the stack. Only available for horizontal stack nodes */
ASStackLayoutAlignItemsFirstBaseline,
/** Children align along the last baseline of the stack. Only available for horizontal stack nodes */
ASStackLayoutAlignItemsLastBaseline,
};
/** /**
Each child may override their parent stack's cross axis alignment. Each child may override their parent stack's cross axis alignment.
@see ASStackLayoutAlignItems @see ASStackLayoutAlignItems
@ -23,8 +66,6 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutAlignSelf) {
ASStackLayoutAlignSelfCenter, ASStackLayoutAlignSelfCenter,
/** Expand to fill cross axis */ /** Expand to fill cross axis */
ASStackLayoutAlignSelfStretch, ASStackLayoutAlignSelfStretch,
/** Children align to their first baseline. Only available for horizontal stack nodes */
ASStackLayoutAlignSelfBaselineFirst, /** Note: All children in a stack must have the same baseline align type */
/** Children align to their last baseline. Only available for horizontal stack nodes */
ASStackLayoutAlignSelfBaselineLast,
}; };

View File

@ -9,49 +9,7 @@
*/ */
#import <AsyncDisplayKit/ASLayoutSpec.h> #import <AsyncDisplayKit/ASLayoutSpec.h>
#import <AsyncDisplayKit/ASStackLayoutDefines.h>
/** The direction children are stacked in */
typedef NS_ENUM(NSUInteger, ASStackLayoutDirection) {
/** Children are stacked vertically */
ASStackLayoutDirectionVertical,
/** Children are stacked horizontally */
ASStackLayoutDirectionHorizontal,
};
/** If no children are flexible, how should this spec justify its children in the available space? */
typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) {
/**
On overflow, children overflow out of this spec's bounds on the right/bottom side.
On underflow, children are left/top-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentStart,
/**
On overflow, children are centered and overflow on both sides.
On underflow, children are centered within this spec's bounds in the stacking direction.
*/
ASStackLayoutJustifyContentCenter,
/**
On overflow, children overflow out of this spec's bounds on the left/top side.
On underflow, children are right/bottom-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentEnd,
};
/** Orientation of children along cross axis */
typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) {
/** Align children to start of cross axis */
ASStackLayoutAlignItemsStart,
/** Align children with end of cross axis */
ASStackLayoutAlignItemsEnd,
/** Center children on cross axis */
ASStackLayoutAlignItemsCenter,
/** Expand children to fill cross axis */
ASStackLayoutAlignItemsStretch,
/** Children align to their first baseline. Only available for horizontal stack nodes */
ASStackLayoutAlignItemsBaselineFirst,
/** Children align to their last baseline. Only available for horizontal stack nodes */
ASStackLayoutAlignItemsBaselineLast,
};
typedef struct { typedef struct {
/** Specifies the direction children are stacked in. */ /** Specifies the direction children are stacked in. */

View File

@ -25,8 +25,9 @@
@implementation ASStackLayoutSpec @implementation ASStackLayoutSpec
{ {
ASStackLayoutSpecStyle _style; ASStackLayoutSpecStyle _style;
std::vector<id<ASLayoutable>> _children; std::vector<id<ASStackLayoutable>> _children;
ASDN::RecursiveMutex _propertyLock; ASDN::RecursiveMutex _propertyLock;
CGFloat _distanceToBaseline;
} }
+ (instancetype)newWithStyle:(ASStackLayoutSpecStyle)style children:(NSArray *)children + (instancetype)newWithStyle:(ASStackLayoutSpecStyle)style children:(NSArray *)children
@ -34,8 +35,10 @@
ASStackLayoutSpec *spec = [super new]; ASStackLayoutSpec *spec = [super new];
if (spec) { if (spec) {
spec->_style = style; spec->_style = style;
spec->_children = std::vector<id<ASLayoutable>>(); spec->_children = std::vector<id<ASStackLayoutable>>();
for (id<ASLayoutable> child in children) { for (id<ASStackLayoutable> child in children) {
ASDisplayNodeAssert([child conformsToProtocol:@protocol(ASStackLayoutable)], @"child must conform to ASStackLayoutable");
spec->_children.push_back(child); spec->_children.push_back(child);
} }
} }
@ -55,12 +58,16 @@
NSArray *sublayouts = [NSArray arrayWithObjects:&positionedLayout.sublayouts[0] count:positionedLayout.sublayouts.size()]; NSArray *sublayouts = [NSArray arrayWithObjects:&positionedLayout.sublayouts[0] count:positionedLayout.sublayouts.size()];
ASDN::MutexLocker l(_propertyLock); ASDN::MutexLocker l(_propertyLock);
self.ascender = positionedLayout.ascender; _distanceToBaseline = positionedLayout.distanceToBaseline;
self.descender = positionedLayout.descender;
return [ASLayout newWithLayoutableObject:self return [ASLayout newWithLayoutableObject:self
size:ASSizeRangeClamp(constrainedSize, finalSize) size:ASSizeRangeClamp(constrainedSize, finalSize)
sublayouts:sublayouts]; sublayouts:sublayouts];
} }
- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType
{
return _distanceToBaseline;
}
@end @end

View File

@ -0,0 +1,57 @@
/*
* 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.
*
*/
#import <AsyncDisplayKit/ASLayoutable.h>
@protocol ASStackLayoutable <ASLayoutable>
/**
* @abstract Additional space to place before this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingBefore;
/**
* @abstract Additional space to place after this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingAfter;
/**
* @abstract If the sum of childrens' stack dimensions is less than the minimum size, should this object grow?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexGrow;
/**
* @abstract If the sum of childrens' stack dimensions is greater than the maximum size, should this object shrink?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexShrink;
/**
* @abstract Specifies the initial size in the stack dimension for this object.
* Default to ASRelativeDimensionUnconstrained.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
/**
* @abstract Orientation of the object along cross axis, overriding alignItems
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
/**
* @abstract Used for baseline alignment in stack spec. The distance from the top of the object to its baseline.
*/
- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType;
@end

View File

@ -55,10 +55,6 @@ inline ASStackLayoutAlignItems alignment(ASStackLayoutAlignSelf childAlignment,
return ASStackLayoutAlignItemsStart; return ASStackLayoutAlignItemsStart;
case ASStackLayoutAlignSelfStretch: case ASStackLayoutAlignSelfStretch:
return ASStackLayoutAlignItemsStretch; return ASStackLayoutAlignItemsStretch;
case ASStackLayoutAlignSelfBaselineFirst:
return ASStackLayoutAlignItemsBaselineFirst;
case ASStackLayoutAlignSelfBaselineLast:
return ASStackLayoutAlignItemsBaselineLast;
case ASStackLayoutAlignSelfAuto: case ASStackLayoutAlignSelfAuto:
default: default:
return stackAlignment; return stackAlignment;

View File

@ -17,8 +17,7 @@
struct ASStackPositionedLayout { struct ASStackPositionedLayout {
const std::vector<ASLayout *> sublayouts; const std::vector<ASLayout *> sublayouts;
const CGFloat crossSize; const CGFloat crossSize;
const CGFloat ascender; const CGFloat distanceToBaseline;
const CGFloat descender;
/** Given an unpositioned layout, computes the positions each child should be placed at. */ /** Given an unpositioned layout, computes the positions each child should be placed at. */
static ASStackPositionedLayout compute(const ASStackUnpositionedLayout &unpositionedLayout, static ASStackPositionedLayout compute(const ASStackUnpositionedLayout &unpositionedLayout,

View File

@ -18,10 +18,8 @@
static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style, static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
const ASStackUnpositionedItem &item) { const ASStackUnpositionedItem &item) {
const ASStackLayoutAlignItems alignItems = alignment(item.child.alignSelf, style.alignItems); const ASStackLayoutAlignItems alignItems = alignment(item.child.alignSelf, style.alignItems);
if (alignItems == ASStackLayoutAlignItemsBaselineFirst) { if (alignItems == ASStackLayoutAlignItemsFirstBaseline || alignItems == ASStackLayoutAlignItemsLastBaseline) {
return item.child.ascender; return [item.child distanceToBaseline:alignItems];
} else if (alignItems == ASStackLayoutAlignItemsBaselineLast) {
return item.layout.size.height + item.child.descender;
} }
return 0; return 0;
} }
@ -39,9 +37,8 @@ static CGFloat crossOffset(const ASStackLayoutSpecStyle &style,
case ASStackLayoutAlignItemsStart: case ASStackLayoutAlignItemsStart:
case ASStackLayoutAlignItemsStretch: case ASStackLayoutAlignItemsStretch:
return 0; return 0;
case ASStackLayoutAlignItemsBaselineFirst: case ASStackLayoutAlignItemsLastBaseline:
return maxBaseline - l.child.ascender; case ASStackLayoutAlignItemsFirstBaseline:
case ASStackLayoutAlignItemsBaselineLast:
return maxBaseline - baselineForItem(style, l); return maxBaseline - baselineForItem(style, l);
} }
} }
@ -78,11 +75,11 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
first = NO; first = NO;
l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize, maxBaseline)); l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize, maxBaseline));
CGFloat spacingAfterBaseline = (style.direction == ASStackLayoutDirectionVertical && style.baselineRelativeArrangement) ? l.child.descender : 0; CGFloat spacingAfterBaseline = (style.direction == ASStackLayoutDirectionVertical && style.baselineRelativeArrangement) ? l.layout.size.height - [l.child distanceToBaseline:style.alignItems] : 0;
p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.spacingAfter + spacingAfterBaseline, 0); p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.spacingAfter + spacingAfterBaseline, 0);
return l.layout; return l.layout;
}); });
return {stackedChildren, crossSize, maxBaseline, maxBaseline == 0 ? 0 : maxBaseline - crossSize}; return {stackedChildren, crossSize, maxBaseline};
} }
ASStackPositionedLayout ASStackPositionedLayout::compute(const ASStackUnpositionedLayout &unpositionedLayout, ASStackPositionedLayout ASStackPositionedLayout::compute(const ASStackUnpositionedLayout &unpositionedLayout,

View File

@ -15,7 +15,7 @@
struct ASStackUnpositionedItem { struct ASStackUnpositionedItem {
/** The original source child. */ /** The original source child. */
id<ASLayoutable> child; id<ASStackLayoutable> child;
/** The proposed layout. */ /** The proposed layout. */
ASLayout *layout; ASLayout *layout;
}; };
@ -30,7 +30,7 @@ struct ASStackUnpositionedLayout {
const CGFloat violation; const CGFloat violation;
/** Given a set of children, computes the unpositioned layouts for those children. */ /** Given a set of children, computes the unpositioned layouts for those children. */
static ASStackUnpositionedLayout compute(const std::vector<id<ASLayoutable>> &children, static ASStackUnpositionedLayout compute(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style, const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange); const ASSizeRange &sizeRange);
}; };

View File

@ -18,7 +18,7 @@
/** /**
Sizes the child given the parameters specified, and returns the computed layout. Sizes the child given the parameters specified, and returns the computed layout.
*/ */
static ASLayout *crossChildLayout(const id<ASLayoutable> child, static ASLayout *crossChildLayout(const id<ASStackLayoutable> child,
const ASStackLayoutSpecStyle style, const ASStackLayoutSpecStyle style,
const CGFloat stackMin, const CGFloat stackMin,
const CGFloat stackMax, const CGFloat stackMax,
@ -186,7 +186,7 @@ static std::function<BOOL(const ASStackUnpositionedItem &)> isFlexibleInViolatio
} }
} }
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child) ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASStackLayoutable> child)
{ {
return child.flexGrow && child.flexShrink; return child.flexGrow && child.flexShrink;
} }
@ -195,7 +195,7 @@ ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
If we have a single flexible (both shrinkable and growable) child, and our allowed size range is set to a specific If we have a single flexible (both shrinkable and growable) child, and our allowed size range is set to a specific
number then we may avoid the first "intrinsic" size calculation. number then we may avoid the first "intrinsic" size calculation.
*/ */
ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASLayoutable>> &children, ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style, const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange) const ASSizeRange &sizeRange)
{ {
@ -283,7 +283,7 @@ static void flexChildrenAlongStackDimension(std::vector<ASStackUnpositionedItem>
Performs the first unconstrained layout of the children, generating the unpositioned items that are then flexed and Performs the first unconstrained layout of the children, generating the unpositioned items that are then flexed and
stretched. stretched.
*/ */
static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASLayoutable>> &children, static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style, const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange, const ASSizeRange &sizeRange,
const CGSize size, const CGSize size,
@ -292,7 +292,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min); const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min);
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max); const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
return AS::map(children, [&](id<ASLayoutable> child) -> ASStackUnpositionedItem { return AS::map(children, [&](id<ASStackLayoutable> child) -> ASStackUnpositionedItem {
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, child.flexBasis); const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, child.flexBasis);
const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.flexBasis, stackDimension(style.direction, size)); const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.flexBasis, stackDimension(style.direction, size));
@ -312,7 +312,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
}); });
} }
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASLayoutable>> &children, ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style, const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange) const ASSizeRange &sizeRange)
{ {