mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-23 11:27:56 +08:00
[Layout] Add style property to ASLayoutable (#2261)
* Add style property to ASLayoutable * Add styles property to further layout specs * Adjust some examples * Add `loadStyle` to create the style object in a ASLayoutable * Revert "Add `loadStyle` to create the style object in a ASLayoutable" This reverts commit 2b7240f2c7dc993e38cadf290cfdf08482dd70c7. * Revert "Adjust some examples" This reverts commit 3254ae0a321e75db3ecfa80adee9d96bde93a33d. * Revert "Add styles property to further layout specs" This reverts commit c779dcb876ead27122c1af1300146a6ad36912cb. * Rename ASLayoutableStyleDeclaration to ASLayoutableStyle * Add styleClass class property for extensibility support of the ASLayoutable style object * flexShrink should not be YES by default
This commit is contained in:
committed by
GitHub
parent
a9857f9963
commit
75dca556e6
@@ -78,7 +78,7 @@
|
||||
// of the button node to add a touch handler.
|
||||
[_titleNode setLayerBacked:YES];
|
||||
#endif
|
||||
[_titleNode setFlexShrink:YES];
|
||||
_titleNode.style.flexShrink = YES;
|
||||
}
|
||||
return _titleNode;
|
||||
}
|
||||
@@ -517,8 +517,8 @@
|
||||
#if DEBUG
|
||||
NSLog(@"Using -[ASDisplayNde preferredFrameSize] is deprecated.");
|
||||
#endif
|
||||
stack.width = ASDimensionMake(ASDimensionUnitPoints, self.preferredFrameSize.width);
|
||||
stack.height = ASDimensionMake(ASDimensionUnitPoints, self.preferredFrameSize.height);
|
||||
stack.style.width = ASDimensionMake(ASDimensionUnitPoints, self.preferredFrameSize.width);
|
||||
stack.style.height = ASDimensionMake(ASDimensionUnitPoints, self.preferredFrameSize.height);
|
||||
spec = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[stack]];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@@ -70,14 +70,7 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
|
||||
|
||||
@implementation ASDisplayNode
|
||||
|
||||
// Dynamic properties for ASLayoutables
|
||||
@dynamic layoutableType, size;
|
||||
// Dynamic properties for sizing
|
||||
@dynamic width, height, minWidth, maxWidth, minHeight, maxHeight;
|
||||
// Dynamic properties for stack spec
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender;
|
||||
// Dynamic properties for static spec
|
||||
@dynamic layoutPosition;
|
||||
@dynamic layoutableType;
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize isFinalLayoutable = _isFinalLayoutable;
|
||||
@@ -307,7 +300,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
_contentsScaleForDisplay = ASScreenScale();
|
||||
_displaySentinel = [[ASSentinel alloc] init];
|
||||
|
||||
_size = ASLayoutableSizeMake();
|
||||
_style = [[[[self class] styleClass] alloc] init];
|
||||
_preferredFrameSize = CGSizeZero;
|
||||
_environmentState = ASEnvironmentStateMakeDefault();
|
||||
|
||||
@@ -728,25 +721,20 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
return _flags.layerBacked;
|
||||
}
|
||||
|
||||
#pragma mark - Layout measurement and sizing
|
||||
#pragma mark - Style
|
||||
|
||||
- (ASLayoutableSize)size
|
||||
+ (Class)styleClass
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size;
|
||||
return [ASLayoutableStyle class];
|
||||
}
|
||||
|
||||
- (void)setSize:(ASLayoutableSize)size
|
||||
- (ASLayoutableStyle *)style
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
if (ASLayoutableSizeEqualToLayoutableSize(_size, size) == NO) {
|
||||
_size = size;
|
||||
[self invalidateCalculatedLayout];
|
||||
}
|
||||
return _style;
|
||||
}
|
||||
|
||||
ASLayoutableSizeForwarding
|
||||
ASLayoutableSizeHelperForwarding
|
||||
#pragma mark - Layout
|
||||
|
||||
- (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
@@ -770,7 +758,7 @@ ASLayoutableSizeHelperForwarding
|
||||
// Prepare for layout transition
|
||||
auto previousLayout = _calculatedDisplayNodeLayout;
|
||||
auto pendingLayout = std::make_shared<ASDisplayNodeLayout>(
|
||||
[self calculateLayoutThatFits:constrainedSize restrictedToSize:_size relativeToParentSize:parentSize],
|
||||
[self calculateLayoutThatFits:constrainedSize restrictedToSize:_style.size relativeToParentSize:parentSize],
|
||||
constrainedSize,
|
||||
parentSize
|
||||
);
|
||||
@@ -887,7 +875,7 @@ ASLayoutableSizeHelperForwarding
|
||||
BOOL automaticallyManagesSubnodesDisabled = (self.automaticallyManagesSubnodes == NO);
|
||||
self.automaticallyManagesSubnodes = YES; // Temporary flag for 1.9.x
|
||||
newLayout = [self calculateLayoutThatFits:constrainedSize
|
||||
restrictedToSize:_size
|
||||
restrictedToSize:_style.size
|
||||
relativeToParentSize:constrainedSize.max];
|
||||
if (automaticallyManagesSubnodesDisabled) {
|
||||
self.automaticallyManagesSubnodes = NO; // Temporary flag for 1.9.x
|
||||
@@ -2418,7 +2406,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
restrictedToSize:(ASLayoutableSize)size
|
||||
relativeToParentSize:(CGSize)parentSize
|
||||
{
|
||||
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, ASLayoutableSizeResolve(_size, parentSize));
|
||||
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, ASLayoutableSizeResolve(_style.size, parentSize));
|
||||
return [self calculateLayoutThatFits:resolvedRange];
|
||||
}
|
||||
|
||||
@@ -2572,8 +2560,8 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
if (! CGSizeEqualToSize(_preferredFrameSize, preferredFrameSize)) {
|
||||
_preferredFrameSize = preferredFrameSize;
|
||||
|
||||
self.width = ASDimensionMake(preferredFrameSize.width);
|
||||
self.height = ASDimensionMake(preferredFrameSize.height);
|
||||
self.style.width = ASDimensionMake(preferredFrameSize.width);
|
||||
self.style.height = ASDimensionMake(preferredFrameSize.height);
|
||||
|
||||
[self invalidateCalculatedLayout];
|
||||
}
|
||||
@@ -3460,9 +3448,6 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
|
||||
}
|
||||
}
|
||||
|
||||
ASEnvironmentLayoutOptionsForwarding
|
||||
ASEnvironmentLayoutExtensibilityForwarding
|
||||
|
||||
- (ASTraitCollection *)asyncTraitCollection
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
@@ -3474,6 +3459,8 @@ ASEnvironmentLayoutExtensibilityForwarding
|
||||
// Subclass override
|
||||
}
|
||||
|
||||
ASEnvironmentLayoutExtensibilityForwarding
|
||||
|
||||
#if TARGET_OS_TV
|
||||
#pragma mark - UIFocusEnvironment Protocol (tvOS)
|
||||
|
||||
|
||||
@@ -372,12 +372,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
CGSize size = renderer.size;
|
||||
if (_attributedText.length > 0) {
|
||||
self.ascender = [[self class] ascenderWithAttributedString:_attributedText];
|
||||
self.descender = [[_attributedText attribute:NSFontAttributeName atIndex:_attributedText.length - 1 effectiveRange:NULL] descender];
|
||||
self.style.ascender = [[self class] ascenderWithAttributedString:_attributedText];
|
||||
self.style.descender = [[_attributedText attribute:NSFontAttributeName atIndex:_attributedText.length - 1 effectiveRange:NULL] descender];
|
||||
if (renderer.currentScaleFactor > 0 && renderer.currentScaleFactor < 1.0) {
|
||||
// while not perfect, this is a good estimate of what the ascender of the scaled font will be.
|
||||
self.ascender *= renderer.currentScaleFactor;
|
||||
self.descender *= renderer.currentScaleFactor;
|
||||
self.style.ascender *= renderer.currentScaleFactor;
|
||||
self.style.descender *= renderer.currentScaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,8 +431,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
NSUInteger length = attributedText.length;
|
||||
if (length > 0) {
|
||||
self.ascender = [[self class] ascenderWithAttributedString:attributedText];
|
||||
self.descender = [[attributedText attribute:NSFontAttributeName atIndex:attributedText.length - 1 effectiveRange:NULL] descender];
|
||||
self.style.ascender = [[self class] ascenderWithAttributedString:attributedText];
|
||||
self.style.descender = [[attributedText attribute:NSFontAttributeName atIndex:attributedText.length - 1 effectiveRange:NULL] descender];
|
||||
}
|
||||
|
||||
// Tell the display node superclasses that the cached layout is incorrect now
|
||||
|
||||
@@ -261,8 +261,8 @@ static NSString * const kRate = @"rate";
|
||||
}
|
||||
|
||||
if (_playerNode) {
|
||||
_playerNode.width = ASDimensionMake(calculatedSize.width);
|
||||
_playerNode.height = ASDimensionMake(calculatedSize.height);
|
||||
_playerNode.style.width = ASDimensionMake(calculatedSize.width);
|
||||
_playerNode.style.height = ASDimensionMake(calculatedSize.height);
|
||||
[_playerNode layoutThatFits:ASSizeRangeMake(CGSizeZero, calculatedSize)];
|
||||
}
|
||||
|
||||
|
||||
@@ -324,8 +324,8 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
{
|
||||
if (_playbackButtonNode == nil) {
|
||||
_playbackButtonNode = [[ASDefaultPlaybackButton alloc] init];
|
||||
_playbackButtonNode.width = ASDimensionMakeWithPoints(16.0);
|
||||
_playbackButtonNode.height = ASDimensionMakeWithPoints(22.0);
|
||||
_playbackButtonNode.style.width = ASDimensionMakeWithPoints(16.0);
|
||||
_playbackButtonNode.style.height = ASDimensionMakeWithPoints(22.0);
|
||||
|
||||
if (_delegateFlags.delegatePlaybackButtonTint) {
|
||||
_playbackButtonNode.tintColor = [_delegate videoPlayerNodePlaybackButtonTint:self];
|
||||
@@ -406,7 +406,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
return slider;
|
||||
}];
|
||||
|
||||
_scrubberNode.flexShrink = YES;
|
||||
_scrubberNode.style.flexShrink = YES;
|
||||
|
||||
[_cachedControls setObject:_scrubberNode forKey:@(ASVideoPlayerNodeControlTypeScrubber)];
|
||||
}
|
||||
@@ -418,7 +418,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
{
|
||||
if (_controlFlexGrowSpacerSpec == nil) {
|
||||
_controlFlexGrowSpacerSpec = [[ASStackLayoutSpec alloc] init];
|
||||
_controlFlexGrowSpacerSpec.flexGrow = YES;
|
||||
_controlFlexGrowSpacerSpec.style.flexGrow = YES;
|
||||
}
|
||||
|
||||
[_cachedControls setObject:_controlFlexGrowSpacerSpec forKey:@(ASVideoPlayerNodeControlTypeFlexGrowSpacer)];
|
||||
@@ -601,8 +601,8 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
return spinnnerView;
|
||||
}];
|
||||
|
||||
_spinnerNode.width = ASDimensionMakeWithPoints(44.0);
|
||||
_spinnerNode.height = ASDimensionMakeWithPoints(44.0);
|
||||
_spinnerNode.style.width = ASDimensionMakeWithPoints(44.0);
|
||||
_spinnerNode.style.height = ASDimensionMakeWithPoints(44.0);
|
||||
|
||||
[self addSubnode:_spinnerNode];
|
||||
[self setNeedsLayout];
|
||||
@@ -705,7 +705,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
ASDisplayNodeAssert(NO, @"Infinite width or height in ASVideoPlayerNode");
|
||||
maxSize = CGSizeZero;
|
||||
}
|
||||
_videoNode.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
_videoNode.style.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
|
||||
ASLayoutSpec *layoutSpec;
|
||||
if (_delegateFlags.delegateLayoutSpecForControls) {
|
||||
@@ -718,12 +718,12 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
|
||||
if (_spinnerNode) {
|
||||
ASCenterLayoutSpec *centerLayoutSpec = [ASCenterLayoutSpec centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY sizingOptions:ASCenterLayoutSpecSizingOptionDefault child:_spinnerNode];
|
||||
centerLayoutSpec.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
centerLayoutSpec.style.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
[children addObject:centerLayoutSpec];
|
||||
}
|
||||
|
||||
ASOverlayLayoutSpec *overlaySpec = [ASOverlayLayoutSpec overlayLayoutSpecWithChild:_videoNode overlay:layoutSpec];
|
||||
overlaySpec.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
overlaySpec.style.size = ASLayoutableSizeMakeFromCGSize(maxSize);
|
||||
[children addObject:overlaySpec];
|
||||
|
||||
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:children];
|
||||
@@ -731,24 +731,24 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
||||
|
||||
- (ASLayoutSpec *)defaultLayoutSpecThatFits:(CGSize)maxSize
|
||||
{
|
||||
_scrubberNode.width = ASDimensionMakeWithPoints(maxSize.width);
|
||||
_scrubberNode.height = ASDimensionMakeWithPoints(44.0);
|
||||
_scrubberNode.style.width = ASDimensionMakeWithPoints(maxSize.width);
|
||||
_scrubberNode.style.height = ASDimensionMakeWithPoints(44.0);
|
||||
|
||||
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
|
||||
spacer.flexGrow = YES;
|
||||
spacer.style.flexGrow = YES;
|
||||
|
||||
ASStackLayoutSpec *controlbarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
||||
spacing:10.0
|
||||
justifyContent:ASStackLayoutJustifyContentStart
|
||||
alignItems:ASStackLayoutAlignItemsCenter
|
||||
children: [self controlsForLayoutSpec] ];
|
||||
controlbarSpec.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||
controlbarSpec.style.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||
|
||||
UIEdgeInsets insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
||||
|
||||
ASInsetLayoutSpec *controlbarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:controlbarSpec];
|
||||
|
||||
controlbarInsetSpec.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||
controlbarInsetSpec.style.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||
|
||||
ASStackLayoutSpec *mainVerticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
|
||||
spacing:0.0
|
||||
|
||||
@@ -26,23 +26,16 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
|
||||
|
||||
@interface ASLayoutSpec() {
|
||||
ASDN::RecursiveMutex __instanceLock__;
|
||||
ASLayoutableSize _size;
|
||||
ASEnvironmentState _environmentState;
|
||||
ASChildMap _children;
|
||||
ASEnvironmentState _environmentState;
|
||||
ASLayoutableStyle *_style;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ASLayoutSpec
|
||||
|
||||
// Dynamic properties for ASLayoutables
|
||||
@dynamic layoutableType, size;
|
||||
// Dynamic properties for sizing
|
||||
@dynamic width, height, minWidth, maxWidth, minHeight, maxHeight;
|
||||
// Dynamic properties for stack spec
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender;
|
||||
// Dynamic properties for static spec
|
||||
@dynamic layoutPosition;
|
||||
|
||||
@dynamic layoutableType;
|
||||
@synthesize isFinalLayoutable = _isFinalLayoutable;
|
||||
|
||||
#pragma mark - Class
|
||||
@@ -63,9 +56,11 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
|
||||
if (!(self = [super init])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_isMutable = YES;
|
||||
_size = ASLayoutableSizeMake();
|
||||
_environmentState = ASEnvironmentStateMakeDefault();
|
||||
_style = [[[[self class] styleClass] alloc] init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -79,25 +74,19 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Style
|
||||
|
||||
#pragma mark - Sizing
|
||||
|
||||
- (ASLayoutableSize)size
|
||||
+ (Class)styleClass
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size;
|
||||
return [ASLayoutableStyle class];
|
||||
}
|
||||
|
||||
- (void)setSize:(ASLayoutableSize)size
|
||||
- (ASLayoutableStyle *)style
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size = size;
|
||||
return _style;
|
||||
}
|
||||
|
||||
ASLayoutableSizeForwarding
|
||||
ASLayoutableSizeHelperForwarding
|
||||
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
// Deprecated
|
||||
@@ -113,14 +102,14 @@ ASLayoutableSizeHelperForwarding
|
||||
|
||||
- (ASLayout *)layoutThatFits:(ASSizeRange)constrainedSize parentSize:(CGSize)parentSize
|
||||
{
|
||||
return [self calculateLayoutThatFits:constrainedSize restrictedToSize:_size relativeToParentSize:parentSize];
|
||||
return [self calculateLayoutThatFits:constrainedSize restrictedToSize:_style.size relativeToParentSize:parentSize];
|
||||
}
|
||||
|
||||
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
||||
restrictedToSize:(ASLayoutableSize)size
|
||||
relativeToParentSize:(CGSize)parentSize
|
||||
{
|
||||
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, ASLayoutableSizeResolve(_size, parentSize));
|
||||
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, ASLayoutableSizeResolve(_style.size, parentSize));
|
||||
return [self calculateLayoutThatFits:resolvedRange];
|
||||
}
|
||||
|
||||
@@ -285,15 +274,14 @@ ASLayoutableSizeHelperForwarding
|
||||
_environmentState.environmentTraitCollection = environmentTraitCollection;
|
||||
}
|
||||
|
||||
ASEnvironmentLayoutOptionsForwarding
|
||||
ASEnvironmentLayoutExtensibilityForwarding
|
||||
|
||||
- (ASTraitCollection *)asyncTraitCollection
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:self.environmentTraitCollection];
|
||||
}
|
||||
|
||||
ASEnvironmentLayoutExtensibilityForwarding
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ static NSString *ASLayoutValidationWrappingAssertMessage(SEL selector, id obj, C
|
||||
Class stackContainerClass = [ASStaticLayoutSpec class];
|
||||
|
||||
// Check for default layoutPosition
|
||||
if (!CGPointEqualToPoint(sublayoutLayoutable.layoutPosition, CGPointZero)) {
|
||||
if (!CGPointEqualToPoint(sublayoutLayoutable.style.layoutPosition, CGPointZero)) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(layoutPosition), sublayoutLayoutable, stackContainerClass);
|
||||
}
|
||||
|
||||
@@ -104,17 +104,17 @@ static NSString *ASLayoutValidationWrappingAssertMessage(SEL selector, id obj, C
|
||||
Class stackContainerClass = [ASStackLayoutSpec class];
|
||||
|
||||
// Check if default values related to ASStackLayoutSpec have changed
|
||||
if (sublayoutLayoutable.spacingBefore != 0) {
|
||||
if (sublayoutLayoutable.style.spacingBefore != 0) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(spacingBefore), sublayoutLayoutable, stackContainerClass);
|
||||
} else if (sublayoutLayoutable.spacingAfter != 0) {
|
||||
} else if (sublayoutLayoutable.style.spacingAfter != 0) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(spacingAfter), sublayoutLayoutable, stackContainerClass);
|
||||
} else if (sublayoutLayoutable.flexGrow == YES) {
|
||||
} else if (sublayoutLayoutable.style.flexGrow == YES) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexGrow), sublayoutLayoutable, stackContainerClass);
|
||||
} else if (sublayoutLayoutable.flexShrink == YES) {
|
||||
} else if (sublayoutLayoutable.style.flexShrink == YES) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexShrink), sublayoutLayoutable, stackContainerClass);
|
||||
} else if (!ASDimensionEqualToDimension(sublayoutLayoutable.flexBasis, ASDimensionAuto) ) {
|
||||
} else if (!ASDimensionEqualToDimension(sublayoutLayoutable.style.flexBasis, ASDimensionAuto) ) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexBasis), sublayoutLayoutable, stackContainerClass);
|
||||
} else if (sublayoutLayoutable.alignSelf != ASStackLayoutAlignSelfAuto) {
|
||||
} else if (sublayoutLayoutable.style.alignSelf != ASStackLayoutAlignSelfAuto) {
|
||||
assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(alignSelf), sublayoutLayoutable, stackContainerClass);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* access to the options via convenience properties. If you are creating custom layout spec, then you can
|
||||
* extend the backing layout options class to accommodate any new layout options.
|
||||
*/
|
||||
@protocol ASLayoutable <ASEnvironment, ASStackLayoutable, ASStaticLayoutable, ASLayoutablePrivate, ASLayoutableExtensibility>
|
||||
@protocol ASLayoutable <ASEnvironment, ASLayoutablePrivate, ASLayoutableExtensibility>
|
||||
|
||||
#pragma mark - Getter
|
||||
|
||||
/**
|
||||
* @abstract Returns type of layoutable
|
||||
@@ -62,63 +64,19 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) BOOL canLayoutAsynchronous;
|
||||
|
||||
#pragma mark - Sizing
|
||||
/**
|
||||
* @abstract A size constraint that should apply to this ASLayoutable.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) ASLayoutableStyle *style;
|
||||
|
||||
/**
|
||||
* @abstract The width property specifies the height of the content area of an ASLayoutable.
|
||||
* The minWidth and maxWidth properties override width.
|
||||
* Defaults to ASRelativeDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension width;
|
||||
|
||||
/**
|
||||
* @abstract The height property specifies the height of the content area of an ASLayoutable
|
||||
* The minHeight and maxHeight properties override height.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension height;
|
||||
|
||||
/**
|
||||
* @abstract The minHeight property is used to set the minimum height of a given element. It prevents the used value
|
||||
* of the height property from becoming smaller than the value specified for minHeight.
|
||||
* The value of minHeight overrides both maxHeight and height.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension minHeight;
|
||||
|
||||
/**
|
||||
* @abstract The maxHeight property is used to set the maximum height of an element. It prevents the used value of the
|
||||
* height property from becoming larger than the value specified for maxHeight.
|
||||
* The value of maxHeight overrides height, but minHeight overrides maxHeight.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension maxHeight;
|
||||
|
||||
/**
|
||||
* @abstract The minWidth property is used to set the minimum width of a given element. It prevents the used value of
|
||||
* the width property from becoming smaller than the value specified for minWidth.
|
||||
* The value of minWidth overrides both maxWidth and width.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension minWidth;
|
||||
|
||||
/**
|
||||
* @abstract The maxWidth property is used to set the maximum width of a given element. It prevents the used value of
|
||||
* the width property from becoming larger than the value specified for maxWidth.
|
||||
* The value of maxWidth overrides width, but minWidth overrides maxWidth.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension maxWidth;
|
||||
|
||||
/**
|
||||
* @abstract Set max and width properties from given size
|
||||
*/
|
||||
- (void)setSizeWithCGSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* @abstract Set minHeight, maxHeight and minWidth, maxWidth properties from given size
|
||||
*/
|
||||
- (void)setExactSizeWithCGSize:(CGSize)size;
|
||||
* @discussion This property contains the ASLayoutableStyle class object by default. Subclasses can use this property to
|
||||
* return a different size class as needed. For example, if your layoutable would like extend the style object to support
|
||||
* more properties you might want to set this property to a custom subclass of ASLayoutableStyle.
|
||||
*
|
||||
* This property is set only once early in the creation of the layoutable to create the corresponding style object.
|
||||
*/
|
||||
@property (class, nonatomic, readonly) Class styleClass;
|
||||
|
||||
|
||||
#pragma mark - Calculate layout
|
||||
@@ -187,67 +145,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
relativeToParentSize:(CGSize)parentSize;
|
||||
|
||||
|
||||
|
||||
#pragma mark - Layout options from the Layoutable Protocols
|
||||
|
||||
|
||||
#pragma mark - ASStackLayoutable
|
||||
/**
|
||||
* @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 ASRelativeDimensionAuto
|
||||
* Used when attached to a stack layout.
|
||||
*/
|
||||
@property (nonatomic, readwrite) ASDimension 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;
|
||||
|
||||
|
||||
#pragma mark - ASStaticLayoutable
|
||||
|
||||
/**
|
||||
* @abstract The position of this object within its parent spec.
|
||||
*/
|
||||
@property (nonatomic, assign) CGPoint layoutPosition;
|
||||
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
/**
|
||||
@@ -263,4 +160,133 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - ASLayoutableStyle
|
||||
|
||||
@interface ASLayoutableStyle : NSObject <ASStackLayoutable, ASStaticLayoutable>
|
||||
|
||||
|
||||
#pragma mark - Sizing
|
||||
|
||||
// TODO: Move to internal method?
|
||||
/**
|
||||
* @abstract A size constraint that should apply to this ASLayoutable.
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASLayoutableSize size;
|
||||
|
||||
/**
|
||||
* @abstract The width property specifies the height of the content area of an ASLayoutable.
|
||||
* The minWidth and maxWidth properties override width.
|
||||
* Defaults to ASRelativeDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension width;
|
||||
|
||||
/**
|
||||
* @abstract The height property specifies the height of the content area of an ASLayoutable
|
||||
* The minHeight and maxHeight properties override height.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension height;
|
||||
|
||||
/**
|
||||
* @abstract The minHeight property is used to set the minimum height of a given element. It prevents the used value
|
||||
* of the height property from becoming smaller than the value specified for minHeight.
|
||||
* The value of minHeight overrides both maxHeight and height.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension minHeight;
|
||||
|
||||
/**
|
||||
* @abstract The maxHeight property is used to set the maximum height of an element. It prevents the used value of the
|
||||
* height property from becoming larger than the value specified for maxHeight.
|
||||
* The value of maxHeight overrides height, but minHeight overrides maxHeight.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension maxHeight;
|
||||
|
||||
/**
|
||||
* @abstract The minWidth property is used to set the minimum width of a given element. It prevents the used value of
|
||||
* the width property from becoming smaller than the value specified for minWidth.
|
||||
* The value of minWidth overrides both maxWidth and width.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension minWidth;
|
||||
|
||||
/**
|
||||
* @abstract The maxWidth property is used to set the maximum width of a given element. It prevents the used value of
|
||||
* the width property from becoming larger than the value specified for maxWidth.
|
||||
* The value of maxWidth overrides width, but minWidth overrides maxWidth.
|
||||
* Defaults to ASDimensionTypeAuto
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASDimension maxWidth;
|
||||
|
||||
/**
|
||||
* @abstract Set max and width properties from given size
|
||||
*/
|
||||
- (void)setSizeWithCGSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* @abstract Set minHeight, maxHeight and minWidth, maxWidth properties from given size
|
||||
*/
|
||||
- (void)setExactSizeWithCGSize:(CGSize)size;
|
||||
|
||||
|
||||
#pragma mark - ASStackLayoutable
|
||||
|
||||
/**
|
||||
* @abstract Additional space to place before this object in the stacking direction.
|
||||
* Used when attached to a stack layout.
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat spacingBefore;
|
||||
|
||||
/**
|
||||
* @abstract Additional space to place after this object in the stacking direction.
|
||||
* Used when attached to a stack layout.
|
||||
*/
|
||||
@property (nonatomic, assign) 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, assign) 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, assign) BOOL flexShrink;
|
||||
|
||||
/**
|
||||
* @abstract Specifies the initial size in the stack dimension for this object.
|
||||
* Default to ASRelativeDimensionAuto
|
||||
* Used when attached to a stack layout.
|
||||
*/
|
||||
@property (nonatomic, assign) ASDimension flexBasis;
|
||||
|
||||
/**
|
||||
* @abstract Orientation of the object along cross axis, overriding alignItems
|
||||
* Used when attached to a stack layout.
|
||||
*/
|
||||
@property (nonatomic, assign) ASStackLayoutAlignSelf alignSelf;
|
||||
|
||||
/**
|
||||
* @abstract Used for baseline alignment. The distance from the top of the object to its baseline.
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat ascender;
|
||||
|
||||
/**
|
||||
* @abstract Used for baseline alignment. The distance from the baseline of the object to its bottom.
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat descender;
|
||||
|
||||
|
||||
#pragma mark - ASStaticLayoutable
|
||||
|
||||
/**
|
||||
* @abstract The position of this object within its parent spec.
|
||||
*/
|
||||
@property (nonatomic, assign) CGPoint layoutPosition;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "ASLayoutablePrivate.h"
|
||||
#import "ASEnvironmentInternal.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASThread.h"
|
||||
|
||||
#import <map>
|
||||
|
||||
@@ -82,3 +83,113 @@ void ASLayoutableClearCurrentContext()
|
||||
ASDN::StaticMutexLocker l(_layoutableContextLock);
|
||||
layoutableContextMap.erase(key);
|
||||
}
|
||||
|
||||
#pragma mark - ASLayoutableStyle
|
||||
|
||||
@implementation ASLayoutableStyle {
|
||||
ASDN::RecursiveMutex __instanceLock__;
|
||||
}
|
||||
|
||||
@dynamic width, height, minWidth, maxWidth, minHeight, maxHeight;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_size = ASLayoutableSizeMake();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - ASLayoutableSizeForwarding
|
||||
|
||||
- (ASDimension)width
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.width;
|
||||
}
|
||||
|
||||
- (void)setWidth:(ASDimension)width
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.width = width;
|
||||
}
|
||||
|
||||
- (ASDimension)height
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.height;
|
||||
}
|
||||
|
||||
- (void)setHeight:(ASDimension)height
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.height = height;
|
||||
}
|
||||
|
||||
- (ASDimension)minWidth
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.minWidth;
|
||||
}
|
||||
|
||||
- (void)setMinWidth:(ASDimension)minWidth
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.minWidth = minWidth;
|
||||
}
|
||||
|
||||
- (ASDimension)maxWidth
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.maxWidth;
|
||||
}
|
||||
|
||||
- (void)setMaxWidth:(ASDimension)maxWidth
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.maxWidth = maxWidth;
|
||||
}
|
||||
|
||||
- (ASDimension)minHeight
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.minHeight;
|
||||
}
|
||||
|
||||
- (void)setMinHeight:(ASDimension)minHeight
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.minHeight = minHeight;
|
||||
}
|
||||
|
||||
- (ASDimension)maxHeight
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
return _size.maxHeight;
|
||||
}
|
||||
|
||||
- (void)setMaxHeight:(ASDimension)maxHeight
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
_size.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
#pragma mark - Layout measurement and sizing
|
||||
|
||||
- (void)setSizeWithCGSize:(CGSize)size
|
||||
{
|
||||
self.width = ASDimensionMakeWithPoints(size.width);
|
||||
self.height = ASDimensionMakeWithPoints(size.height);
|
||||
}
|
||||
|
||||
- (void)setExactSizeWithCGSize:(CGSize)size
|
||||
{
|
||||
self.minWidth = ASDimensionMakeWithPoints(size.width);
|
||||
self.minHeight = ASDimensionMakeWithPoints(size.height);
|
||||
self.maxWidth = ASDimensionMakeWithPoints(size.width);
|
||||
self.maxHeight = ASDimensionMakeWithPoints(size.height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
#import "ASDimension.h"
|
||||
|
||||
@class ASLayoutSpec;
|
||||
@protocol ASLayoutable;
|
||||
@class ASLayoutableStyle;
|
||||
|
||||
struct ASLayoutableContext {
|
||||
int32_t transitionID;
|
||||
@@ -40,11 +40,6 @@ extern void ASLayoutableClearCurrentContext();
|
||||
*/
|
||||
@protocol ASLayoutablePrivate <NSObject>
|
||||
|
||||
/**
|
||||
* @abstract A size constraint that should apply to this ASLayoutable.
|
||||
*/
|
||||
@property (nonatomic, assign, readwrite) ASLayoutableSize size;
|
||||
|
||||
/**
|
||||
* @abstract This method can be used to give the user a chance to wrap an ASLayoutable in an ASLayoutSpec
|
||||
* just before it is added to a parent ASLayoutSpec. For example, if you wanted an ASTextNode that was always
|
||||
@@ -66,228 +61,6 @@ extern void ASLayoutableClearCurrentContext();
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - ASLayoutableForwarding
|
||||
/**
|
||||
* Both an ASDisplayNode and an ASLayoutSpec conform to ASLayoutable. There are several properties
|
||||
* in ASLayoutable that are used when a node or spec is used in a layout spec.
|
||||
* These properties are provided for convenience, as they are forwards to the node or spec's
|
||||
* properties. Instead of duplicating the property forwarding in both classes, we
|
||||
* create a define that allows us to easily implement the forwards in one place.
|
||||
*
|
||||
* If you create a custom layout spec, we recommend this stragety if you decide to extend
|
||||
* ASDisplayNode and ASLayoutSpec to provide convenience properties for any options that your
|
||||
* layoutSpec may require.
|
||||
*/
|
||||
|
||||
#pragma mark - ASLayoutableSizeForwarding
|
||||
|
||||
#define ASLayoutableSizeForwarding \
|
||||
\
|
||||
- (ASDimension)width\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.width;\
|
||||
}\
|
||||
\
|
||||
- (void)setWidth:(ASDimension)width\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.width = width;\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)height\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.height;\
|
||||
}\
|
||||
\
|
||||
- (void)setHeight:(ASDimension)height\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.height = height;\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)minWidth\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.minWidth;\
|
||||
}\
|
||||
\
|
||||
- (void)setMinWidth:(ASDimension)minWidth\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.minWidth = minWidth;\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)maxWidth\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.maxWidth;\
|
||||
}\
|
||||
\
|
||||
- (void)setMaxWidth:(ASDimension)maxWidth\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.maxWidth = maxWidth;\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)minHeight\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.minHeight;\
|
||||
}\
|
||||
\
|
||||
- (void)setMinHeight:(ASDimension)minHeight\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.minHeight = minHeight;\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)maxHeight\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
return _size.maxHeight;\
|
||||
}\
|
||||
\
|
||||
- (void)setMaxHeight:(ASDimension)maxHeight\
|
||||
{\
|
||||
ASDN::MutexLocker l(__instanceLock__);\
|
||||
_size.maxHeight = maxHeight;\
|
||||
}\
|
||||
|
||||
|
||||
#pragma mark - ASLayoutableSizeHelperForwarding
|
||||
|
||||
#define ASLayoutableSizeHelperForwarding \
|
||||
- (void)setSizeWithCGSize:(CGSize)size\
|
||||
{\
|
||||
self.width = ASDimensionMakeWithPoints(size.width);\
|
||||
self.height = ASDimensionMakeWithPoints(size.height);\
|
||||
}\
|
||||
\
|
||||
- (void)setExactSizeWithCGSize:(CGSize)size\
|
||||
{\
|
||||
self.minWidth = ASDimensionMakeWithPoints(size.width);\
|
||||
self.minHeight = ASDimensionMakeWithPoints(size.height);\
|
||||
self.maxWidth = ASDimensionMakeWithPoints(size.width);\
|
||||
self.maxHeight = ASDimensionMakeWithPoints(size.height);\
|
||||
}\
|
||||
|
||||
|
||||
#pragma mark - ASLayoutOptionsForwarding
|
||||
|
||||
#define ASEnvironmentLayoutOptionsForwarding \
|
||||
- (void)propagateUpLayoutOptionsState\
|
||||
{\
|
||||
if (!ASEnvironmentStatePropagationEnabled()) {\
|
||||
return;\
|
||||
}\
|
||||
id<ASEnvironment> parent = [self parent];\
|
||||
if ([parent supportsUpwardPropagation]) {\
|
||||
ASEnvironmentStatePropagateUp(parent, _environmentState.layoutOptionsState);\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
- (CGFloat)spacingAfter\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.spacingAfter;\
|
||||
}\
|
||||
\
|
||||
- (void)setSpacingAfter:(CGFloat)spacingAfter\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.spacingAfter = spacingAfter;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (CGFloat)spacingBefore\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.spacingBefore;\
|
||||
}\
|
||||
\
|
||||
- (void)setSpacingBefore:(CGFloat)spacingBefore\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.spacingBefore = spacingBefore;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (BOOL)flexGrow\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.flexGrow;\
|
||||
}\
|
||||
\
|
||||
- (void)setFlexGrow:(BOOL)flexGrow\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.flexGrow = flexGrow;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (BOOL)flexShrink\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.flexShrink;\
|
||||
}\
|
||||
\
|
||||
- (void)setFlexShrink:(BOOL)flexShrink\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.flexShrink = flexShrink;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (ASDimension)flexBasis\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.flexBasis;\
|
||||
}\
|
||||
\
|
||||
- (void)setFlexBasis:(ASDimension)flexBasis\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.flexBasis = flexBasis;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (ASStackLayoutAlignSelf)alignSelf\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.alignSelf;\
|
||||
}\
|
||||
\
|
||||
- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.alignSelf = alignSelf;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (CGFloat)ascender\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.ascender;\
|
||||
}\
|
||||
\
|
||||
- (void)setAscender:(CGFloat)ascender\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.ascender = ascender;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (CGFloat)descender\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.descender;\
|
||||
}\
|
||||
\
|
||||
- (void)setDescender:(CGFloat)descender\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.descender = descender;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
\
|
||||
- (CGPoint)layoutPosition\
|
||||
{\
|
||||
return _environmentState.layoutOptionsState.layoutPosition;\
|
||||
}\
|
||||
\
|
||||
- (void)setLayoutPosition:(CGPoint)layoutPosition\
|
||||
{\
|
||||
_environmentState.layoutOptionsState.layoutPosition = layoutPosition;\
|
||||
[self propagateUpLayoutOptionsState];\
|
||||
}\
|
||||
|
||||
|
||||
#pragma mark - ASLayoutableExtensibility
|
||||
|
||||
#define ASEnvironmentLayoutExtensibilityForwarding \
|
||||
|
||||
@@ -143,12 +143,12 @@
|
||||
const auto baselinePositionedLayout = ASStackBaselinePositionedLayout::compute(positionedLayout, style, constrainedSize);
|
||||
if (self.direction == ASStackLayoutDirectionVertical) {
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
self.ascender = [stackChildren.front() ascender];
|
||||
self.descender = [stackChildren.back() descender];
|
||||
self.style.ascender = stackChildren.front().style.ascender;
|
||||
self.style.descender = stackChildren.back().style.descender;
|
||||
} else {
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
self.ascender = baselinePositionedLayout.ascender;
|
||||
self.descender = baselinePositionedLayout.descender;
|
||||
self.style.ascender = baselinePositionedLayout.ascender;
|
||||
self.style.descender = baselinePositionedLayout.descender;
|
||||
}
|
||||
|
||||
if (needsBaselinePass) {
|
||||
|
||||
@@ -46,13 +46,13 @@
|
||||
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:children.count];
|
||||
|
||||
for (id<ASLayoutable> child in children) {
|
||||
CGPoint layoutPosition = child.layoutPosition;
|
||||
CGPoint layoutPosition = child.style.layoutPosition;
|
||||
CGSize autoMaxSize = {
|
||||
constrainedSize.max.width - layoutPosition.x,
|
||||
constrainedSize.max.height - layoutPosition.y
|
||||
};
|
||||
|
||||
const ASSizeRange childConstraint = ASLayoutableSizeResolveAutoSize(child.size, size, {{0,0}, autoMaxSize});
|
||||
const ASSizeRange childConstraint = ASLayoutableSizeResolveAutoSize(child.style.size, size, {{0,0}, autoMaxSize});
|
||||
|
||||
ASLayout *sublayout = [child layoutThatFits:childConstraint parentSize:size];
|
||||
sublayout.position = layoutPosition;
|
||||
|
||||
@@ -106,7 +106,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
|
||||
@protected
|
||||
ASDisplayNode * __weak _supernode;
|
||||
|
||||
ASLayoutableSize _size;
|
||||
ASLayoutableStyle *_style;
|
||||
CGSize _preferredFrameSize;
|
||||
|
||||
ASSentinel *_displaySentinel;
|
||||
|
||||
@@ -18,9 +18,9 @@ static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
|
||||
__weak id<ASLayoutable> child = layout.layoutable;
|
||||
switch (style.alignItems) {
|
||||
case ASStackLayoutAlignItemsBaselineFirst:
|
||||
return child.ascender;
|
||||
return child.style.ascender;
|
||||
case ASStackLayoutAlignItemsBaselineLast:
|
||||
return layout.size.height + child.descender;
|
||||
return layout.size.height + child.style.descender;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -36,7 +36,7 @@ static CGFloat baselineOffset(const ASStackLayoutSpecStyle &style,
|
||||
__weak id<ASLayoutable> child = l.layoutable;
|
||||
switch (style.alignItems) {
|
||||
case ASStackLayoutAlignItemsBaselineFirst:
|
||||
return maxAscender - child.ascender;
|
||||
return maxAscender - child.style.ascender;
|
||||
case ASStackLayoutAlignItemsBaselineLast:
|
||||
return maxBaseline - baselineForItem(style, l);
|
||||
|
||||
@@ -89,9 +89,9 @@ ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const A
|
||||
our layoutSpec to have it so that it can be baseline aligned with another text node or baseline layout spec.
|
||||
*/
|
||||
const auto ascenderIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){
|
||||
return a.layoutable.ascender < b.layoutable.ascender;
|
||||
return a.layoutable.style.ascender < b.layoutable.style.ascender;
|
||||
});
|
||||
const CGFloat maxAscender = ascenderIt == positionedLayout.sublayouts.end() ? 0 : (*ascenderIt).layoutable.ascender;
|
||||
const CGFloat maxAscender = ascenderIt == positionedLayout.sublayouts.end() ? 0 : (*ascenderIt).layoutable.style.ascender;
|
||||
|
||||
/*
|
||||
Step 3: Take each child and update its layout position based on the baseline offset.
|
||||
@@ -109,7 +109,7 @@ ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const A
|
||||
BOOL first = YES;
|
||||
stackedChildren = AS::map(positionedLayout.sublayouts, [&](ASLayout *l) -> ASLayout *{
|
||||
__weak id<ASLayoutable> child = l.layoutable;
|
||||
p = p + directionPoint(style.direction, child.spacingBefore, 0);
|
||||
p = p + directionPoint(style.direction, child.style.spacingBefore, 0);
|
||||
if (first) {
|
||||
// if this is the first item use the previously computed start point
|
||||
p = l.position;
|
||||
@@ -126,9 +126,9 @@ ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const A
|
||||
// node from baselines and not bounding boxes.
|
||||
CGFloat spacingAfterBaseline = 0;
|
||||
if (style.direction == ASStackLayoutDirectionVertical) {
|
||||
spacingAfterBaseline = child.descender;
|
||||
spacingAfterBaseline = child.style.descender;
|
||||
}
|
||||
p = p + directionPoint(style.direction, stackDimension(style.direction, l.size) + child.spacingAfter + spacingAfterBaseline, 0);
|
||||
p = p + directionPoint(style.direction, stackDimension(style.direction, l.size) + child.style.spacingAfter + spacingAfterBaseline, 0);
|
||||
|
||||
return l;
|
||||
});
|
||||
@@ -161,7 +161,7 @@ ASStackBaselinePositionedLayout ASStackBaselinePositionedLayout::compute(const A
|
||||
const auto descenderIt = std::max_element(stackedChildren.begin(), stackedChildren.end(), [&](const ASLayout *a, const ASLayout *b){
|
||||
return a.position.y + a.size.height < b.position.y + b.size.height;
|
||||
});
|
||||
const CGFloat minDescender = descenderIt == stackedChildren.end() ? 0 : (*descenderIt).layoutable.descender;
|
||||
const CGFloat minDescender = descenderIt == stackedChildren.end() ? 0 : (*descenderIt).layoutable.style.descender;
|
||||
|
||||
return {stackedChildren, crossSize, maxAscender, minDescender};
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ static CGFloat crossOffset(const ASStackLayoutSpecStyle &style,
|
||||
const ASStackUnpositionedItem &l,
|
||||
const CGFloat crossSize)
|
||||
{
|
||||
switch (alignment(l.child.alignSelf, style.alignItems)) {
|
||||
switch (alignment(l.child.style.alignSelf, style.alignItems)) {
|
||||
case ASStackLayoutAlignItemsEnd:
|
||||
return crossSize - crossDimension(style.direction, l.layout.size);
|
||||
case ASStackLayoutAlignItemsCenter:
|
||||
@@ -66,14 +66,14 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
|
||||
|
||||
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayout *{
|
||||
offset = (l.child == lastChild) ? lastChildOffset : 0;
|
||||
p = p + directionPoint(style.direction, l.child.spacingBefore + offset, 0);
|
||||
p = p + directionPoint(style.direction, l.child.style.spacingBefore + offset, 0);
|
||||
if (!first) {
|
||||
p = p + directionPoint(style.direction, style.spacing + extraSpacing, 0);
|
||||
}
|
||||
first = NO;
|
||||
l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize));
|
||||
|
||||
p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.spacingAfter, 0);
|
||||
p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.style.spacingAfter, 0);
|
||||
return l.layout;
|
||||
});
|
||||
return {stackedChildren, crossSize};
|
||||
|
||||
@@ -26,7 +26,7 @@ static ASLayout *crossChildLayout(const id<ASLayoutable> child,
|
||||
const CGFloat crossMax,
|
||||
const CGSize size)
|
||||
{
|
||||
const ASStackLayoutAlignItems alignItems = alignment(child.alignSelf, style.alignItems);
|
||||
const ASStackLayoutAlignItems alignItems = alignment(child.style.alignSelf, style.alignItems);
|
||||
// stretched children will have a cross dimension of at least crossMin
|
||||
const CGFloat childCrossMin = alignItems == ASStackLayoutAlignItemsStretch ? crossMin : 0;
|
||||
const ASSizeRange childSizeRange = directionSizeRange(style.direction, stackMin, stackMax, childCrossMin, crossMax);
|
||||
@@ -79,7 +79,7 @@ static void stretchChildrenAlongCrossDimension(std::vector<ASStackUnpositionedIt
|
||||
|
||||
const CGFloat childCrossMax = it == layouts.end() ? 0 : crossDimension(style.direction, it->layout.size);
|
||||
for (auto &l : layouts) {
|
||||
const ASStackLayoutAlignItems alignItems = alignment(l.child.alignSelf, style.alignItems);
|
||||
const ASStackLayoutAlignItems alignItems = alignment(l.child.style.alignSelf, style.alignItems);
|
||||
|
||||
const CGFloat cross = crossDimension(style.direction, l.layout.size);
|
||||
const CGFloat stack = stackDimension(style.direction, l.layout.size);
|
||||
@@ -116,7 +116,7 @@ static CGFloat computeStackDimensionSum(const std::vector<ASStackUnpositionedIte
|
||||
children.empty() ? 0 : style.spacing * (children.size() - 1),
|
||||
[&](CGFloat x, const ASStackUnpositionedItem &l) {
|
||||
const id<ASLayoutable> child = l.child;
|
||||
return x + child.spacingBefore + child.spacingAfter;
|
||||
return x + child.style.spacingBefore + child.style.spacingAfter;
|
||||
});
|
||||
|
||||
// Sum up the childrens' dimensions (including spacing) in the stack direction.
|
||||
@@ -185,15 +185,15 @@ static std::function<BOOL(const ASStackUnpositionedItem &)> isFlexibleInViolatio
|
||||
if (std::fabs(violation) < kViolationEpsilon) {
|
||||
return [](const ASStackUnpositionedItem &l) { return NO; };
|
||||
} else if (violation > 0) {
|
||||
return [](const ASStackUnpositionedItem &l) { return l.child.flexGrow; };
|
||||
return [](const ASStackUnpositionedItem &l) { return l.child.style.flexGrow; };
|
||||
} else {
|
||||
return [](const ASStackUnpositionedItem &l) { return l.child.flexShrink; };
|
||||
return [](const ASStackUnpositionedItem &l) { return l.child.style.flexShrink; };
|
||||
}
|
||||
}
|
||||
|
||||
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
|
||||
{
|
||||
return child.flexGrow && child.flexShrink;
|
||||
return child.style.flexGrow && child.style.flexShrink;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,8 +309,8 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
|
||||
child,
|
||||
crossChildLayout(child,
|
||||
style,
|
||||
ASDimensionResolve(child.flexBasis, stackDimension(style.direction, size), 0),
|
||||
ASDimensionResolve(child.flexBasis, stackDimension(style.direction, size), INFINITY),
|
||||
ASDimensionResolve(child.style.flexBasis, stackDimension(style.direction, size), 0),
|
||||
ASDimensionResolve(child.style.flexBasis, stackDimension(style.direction, size), INFINITY),
|
||||
minCrossDimension,
|
||||
maxCrossDimension,
|
||||
size)
|
||||
|
||||
@@ -90,7 +90,7 @@ static NSString *suffixForCenteringOptions(ASCenterLayoutSpecCenteringOptions ce
|
||||
{
|
||||
ASDisplayNode *backgroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
|
||||
ASDisplayNode *foregroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor], CGSizeMake(10, 10));
|
||||
foregroundNode.flexGrow = YES;
|
||||
foregroundNode.style.flexGrow = YES;
|
||||
|
||||
ASCenterLayoutSpec *layoutSpec =
|
||||
[ASCenterLayoutSpec
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
CGSize nodeSize = CGSizeMake(100, 100);
|
||||
|
||||
ASDisplayNode *displayNode = [[ASDisplayNode alloc] init];
|
||||
displayNode.width = ASDimensionMake(100);
|
||||
displayNode.height = ASDimensionMake(100);
|
||||
displayNode.style.width = ASDimensionMake(100);
|
||||
displayNode.style.height = ASDimensionMake(100);
|
||||
|
||||
// Use a button node in here as ASButtonNode uses layoutSpecThatFits:
|
||||
ASButtonNode *buttonNode = [ASButtonNode new];
|
||||
@@ -80,7 +80,7 @@
|
||||
CGSize nodeSize = CGSizeMake(100, 100);
|
||||
|
||||
ASDisplayNode *displayNode = [ASDisplayNode new];
|
||||
[displayNode setSizeWithCGSize:nodeSize];
|
||||
[displayNode.style setSizeWithCGSize:nodeSize];
|
||||
|
||||
ASButtonNode *buttonNode = [ASButtonNode new];
|
||||
[displayNode addSubnode:buttonNode];
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
imageNode.image = [self testImage];
|
||||
|
||||
// Snapshot testing requires that node is formally laid out.
|
||||
[imageNode setSizeWithCGSize:forcedImageSize];
|
||||
[imageNode.style setSizeWithCGSize:forcedImageSize];
|
||||
[imageNode layoutThatFits:ASSizeRangeMake(CGSizeZero, forcedImageSize)];
|
||||
ASSnapshotVerifyNode(imageNode, @"first");
|
||||
|
||||
[imageNode setSizeWithCGSize:CGSizeMake(200, 200)];
|
||||
[imageNode.style setSizeWithCGSize:CGSizeMake(200, 200)];
|
||||
[imageNode layoutThatFits:ASSizeRangeMake(CGSizeZero, CGSizeMake(200, 200))];
|
||||
|
||||
ASSnapshotVerifyNode(imageNode, @"second");
|
||||
|
||||
@@ -35,8 +35,8 @@ __attribute__((overloadable)) static inline ASDisplayNode *ASDisplayNodeWithBack
|
||||
ASDisplayNode *node = [[ASDisplayNode alloc] init];
|
||||
node.layerBacked = YES;
|
||||
node.backgroundColor = backgroundColor;
|
||||
node.width = ASDimensionMakeWithPoints(size.width);
|
||||
node.height = ASDimensionMakeWithPoints(size.height);
|
||||
node.style.width = ASDimensionMakeWithPoints(size.width);
|
||||
node.style.height = ASDimensionMakeWithPoints(size.height);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ static NSString *suffixForPositionOptions(ASRelativeLayoutSpecPosition horizonta
|
||||
{
|
||||
ASDisplayNode *backgroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
|
||||
ASDisplayNode *foregroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor], CGSizeMake(10, 10));
|
||||
foregroundNode.flexGrow = YES;
|
||||
foregroundNode.style.flexGrow = YES;
|
||||
|
||||
ASLayoutSpec *childSpec =
|
||||
[ASBackgroundLayoutSpec
|
||||
|
||||
@@ -36,27 +36,27 @@ static NSArray<ASDisplayNode *> *defaultSubnodesWithSameSize(CGSize subnodeSize,
|
||||
ASDisplayNodeWithBackgroundColor([UIColor greenColor], subnodeSize)
|
||||
];
|
||||
for (ASDisplayNode *subnode in subnodes) {
|
||||
subnode.flexGrow = flex;
|
||||
subnode.flexShrink = flex;
|
||||
subnode.style.flexGrow = flex;
|
||||
subnode.style.flexShrink = flex;
|
||||
}
|
||||
return subnodes;
|
||||
}
|
||||
|
||||
static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
{
|
||||
node.width = ASDimensionMakeWithPoints(size.width);
|
||||
node.height = ASDimensionMakeWithPoints(size.height);
|
||||
node.style.width = ASDimensionMakeWithPoints(size.width);
|
||||
node.style.height = ASDimensionMakeWithPoints(size.height);
|
||||
}
|
||||
|
||||
- (void)testDefaultStackLayoutableFlexProperties
|
||||
{
|
||||
ASDisplayNode *displayNode = [[ASDisplayNode alloc] init];
|
||||
|
||||
XCTAssertEqual(displayNode.flexShrink, NO);
|
||||
XCTAssertEqual(displayNode.flexGrow, NO);
|
||||
XCTAssertEqual(displayNode.style.flexShrink, NO);
|
||||
XCTAssertEqual(displayNode.style.flexGrow, NO);
|
||||
|
||||
const ASDimension unconstrainedDimension = ASDimensionAuto;
|
||||
const ASDimension flexBasis = displayNode.flexBasis;
|
||||
const ASDimension flexBasis = displayNode.style.flexBasis;
|
||||
XCTAssertEqual(flexBasis.unit, unconstrainedDimension.unit);
|
||||
XCTAssertEqual(flexBasis.value, unconstrainedDimension.value);
|
||||
}
|
||||
@@ -166,7 +166,7 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
ASStackLayoutSpecStyle style = {.direction = ASStackLayoutDirectionHorizontal};
|
||||
|
||||
NSArray<ASDisplayNode *> *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
|
||||
subnodes[1].flexShrink = YES;
|
||||
subnodes[1].style.flexShrink = YES;
|
||||
|
||||
// Width is 75px--that's less than the sum of the widths of the children, which is 100px.
|
||||
static ASSizeRange kSize = {{75, 0}, {75, 150}};
|
||||
@@ -260,23 +260,23 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[1].spacingBefore = 10;
|
||||
subnodes[2].spacingBefore = 20;
|
||||
subnodes[1].style.spacingBefore = 10;
|
||||
subnodes[2].style.spacingBefore = 20;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBefore"];
|
||||
// Reset above spacing values
|
||||
subnodes[1].spacingBefore = 0;
|
||||
subnodes[2].spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 0;
|
||||
subnodes[2].style.spacingBefore = 0;
|
||||
|
||||
subnodes[1].spacingAfter = 10;
|
||||
subnodes[2].spacingAfter = 20;
|
||||
subnodes[1].style.spacingAfter = 10;
|
||||
subnodes[2].style.spacingAfter = 20;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingAfter"];
|
||||
// Reset above spacing values
|
||||
subnodes[1].spacingAfter = 0;
|
||||
subnodes[2].spacingAfter = 0;
|
||||
subnodes[1].style.spacingAfter = 0;
|
||||
subnodes[2].style.spacingAfter = 0;
|
||||
|
||||
style.spacing = 10;
|
||||
subnodes[1].spacingBefore = -10;
|
||||
subnodes[1].spacingAfter = -10;
|
||||
subnodes[1].style.spacingBefore = -10;
|
||||
subnodes[1].style.spacingAfter = -10;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBalancedOut"];
|
||||
}
|
||||
|
||||
@@ -292,9 +292,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
// width 0-300px; height 300px
|
||||
static ASSizeRange kVariableHeight = {{0, 300}, {300, 300}};
|
||||
@@ -351,9 +351,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
ASDisplayNode * subnode2 = ASDisplayNodeWithBackgroundColor([UIColor redColor], {50, 50});
|
||||
|
||||
ASRatioLayoutSpec *child1 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.5 child:subnode1];
|
||||
child1.flexBasis = ASDimensionMakeWithFraction(1);
|
||||
child1.flexGrow = YES;
|
||||
child1.flexShrink = YES;
|
||||
child1.style.flexBasis = ASDimensionMakeWithFraction(1);
|
||||
child1.style.flexGrow = YES;
|
||||
child1.style.flexShrink = YES;
|
||||
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
|
||||
[self testStackLayoutSpecWithStyle:style children:@[child1, subnode2] sizeRange:kFixedWidth subnodes:@[subnode1, subnode2] identifier:nil];
|
||||
@@ -367,10 +367,10 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
};
|
||||
|
||||
ASDisplayNode *subnode1 = ASDisplayNodeWithBackgroundColor([UIColor redColor], {100, 100});
|
||||
subnode1.flexShrink = YES;
|
||||
subnode1.style.flexShrink = YES;
|
||||
|
||||
ASDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor], {50, 50});
|
||||
subnode2.flexShrink = YES;
|
||||
subnode2.style.flexShrink = YES;
|
||||
|
||||
NSArray<ASDisplayNode *> *subnodes = @[subnode1, subnode2];
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, 100}};
|
||||
@@ -384,7 +384,7 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
ASDisplayNode *subnode1 = ASDisplayNodeWithBackgroundColor([UIColor redColor], {100, 100});
|
||||
|
||||
ASDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor], {50, 50});
|
||||
subnode2.alignSelf = ASStackLayoutAlignSelfCenter;
|
||||
subnode2.style.alignSelf = ASStackLayoutAlignSelfCenter;
|
||||
|
||||
NSArray<ASDisplayNode *> *subnodes = @[subnode1, subnode2];
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
|
||||
@@ -404,9 +404,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@@ -425,9 +425,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@@ -446,9 +446,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@@ -467,9 +467,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kVariableSize = {{200, 200}, {300, 300}};
|
||||
// all children should be 200px wide
|
||||
@@ -489,9 +489,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 70}, subnodes[1]);
|
||||
setCGSizeToNode({150, 90}, subnodes[2]);
|
||||
|
||||
subnodes[0].spacingBefore = 0;
|
||||
subnodes[1].spacingBefore = 20;
|
||||
subnodes[2].spacingBefore = 30;
|
||||
subnodes[0].style.spacingBefore = 0;
|
||||
subnodes[1].style.spacingBefore = 20;
|
||||
subnodes[2].style.spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kVariableSize = {{50, 50}, {300, 300}};
|
||||
// all children should be 150px wide
|
||||
@@ -512,8 +512,8 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({150, 150}, subnodes[1]);
|
||||
|
||||
for (ASDisplayNode *subnode in subnodes) {
|
||||
subnode.flexGrow = YES;
|
||||
subnode.flexBasis = ASDimensionMakeWithPoints(10);
|
||||
subnode.style.flexGrow = YES;
|
||||
subnode.style.flexBasis = ASDimensionMakeWithPoints(10);
|
||||
}
|
||||
|
||||
// width 300px; height 0-150px.
|
||||
@@ -531,12 +531,12 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
|
||||
NSArray<ASDisplayNode *> *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
|
||||
for (ASDisplayNode *subnode in subnodes) {
|
||||
subnode.flexGrow = YES;
|
||||
subnode.style.flexGrow = YES;
|
||||
}
|
||||
|
||||
// This should override the intrinsic size of 50pts and instead compute to 50% = 100pts.
|
||||
// The result should be that the red box is twice as wide as the blue and gree boxes after flexing.
|
||||
subnodes[0].flexBasis = ASDimensionMakeWithFraction(0.5);
|
||||
subnodes[0].style.flexBasis = ASDimensionMakeWithFraction(0.5);
|
||||
|
||||
static ASSizeRange kSize = {{200, 0}, {200, INFINITY}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
|
||||
@@ -552,7 +552,7 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({150, 50}, subnodes[2]);
|
||||
|
||||
for (ASDisplayNode *subnode in subnodes) {
|
||||
subnode.flexBasis = ASDimensionMakeWithPoints(20);
|
||||
subnode.style.flexBasis = ASDimensionMakeWithPoints(20);
|
||||
}
|
||||
|
||||
static ASSizeRange kSize = {{300, 0}, {300, 150}};
|
||||
@@ -568,8 +568,8 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
];
|
||||
|
||||
ASRatioLayoutSpec *child2 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.0 child:subnodes[2]];
|
||||
child2.flexGrow = YES;
|
||||
child2.flexShrink = YES;
|
||||
child2.style.flexGrow = YES;
|
||||
child2.style.flexShrink = YES;
|
||||
|
||||
// If cross axis stretching occurred *before* flexing, then the blue child would be stretched to 3000 points tall.
|
||||
// Instead it should be stretched to 300 points tall, matching the red child and not overlapping the green inset.
|
||||
@@ -602,9 +602,9 @@ static void setCGSizeToNode(CGSize size, ASDisplayNode *node)
|
||||
setCGSizeToNode({100, 50}, subnodes[1]);
|
||||
setCGSizeToNode({200, 50}, subnodes[2]);
|
||||
|
||||
subnodes[0].flexShrink = YES;
|
||||
subnodes[1].flexShrink = NO;
|
||||
subnodes[2].flexShrink = YES;
|
||||
subnodes[0].style.flexShrink = YES;
|
||||
subnodes[1].style.flexShrink = NO;
|
||||
subnodes[2].style.flexShrink = YES;
|
||||
|
||||
// A width of 400px results in a violation of 200px. This is distributed equally among each flexible child,
|
||||
// causing both of them to be shrunk by 100px, resulting in widths of 300px, 100px, and 50px.
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
- (void)testChildrenMeasuredWithAutoMaxSize
|
||||
{
|
||||
ASDisplayNode *firstChild = ASDisplayNodeWithBackgroundColor([UIColor redColor], (CGSize){50, 50});
|
||||
firstChild.layoutPosition = CGPointMake(0, 0);
|
||||
firstChild.style.layoutPosition = CGPointMake(0, 0);
|
||||
|
||||
ASDisplayNode *secondChild = ASDisplayNodeWithBackgroundColor([UIColor blueColor], (CGSize){100, 100});
|
||||
secondChild.layoutPosition = CGPointMake(10, 60);
|
||||
secondChild.style.layoutPosition = CGPointMake(10, 60);
|
||||
|
||||
ASSizeRange sizeRange = ASSizeRangeMake(CGSizeMake(10, 10), CGSizeMake(110, 160));
|
||||
[self testWithChildren:@[firstChild, secondChild] sizeRange:sizeRange identifier:nil];
|
||||
@@ -46,10 +46,10 @@
|
||||
- (void)testWithSizeRange:(ASSizeRange)sizeRange identifier:(NSString *)identifier
|
||||
{
|
||||
ASDisplayNode *firstChild = ASDisplayNodeWithBackgroundColor([UIColor redColor], (CGSize){50, 50});
|
||||
firstChild.layoutPosition = CGPointMake(0, 0);
|
||||
firstChild.style.layoutPosition = CGPointMake(0, 0);
|
||||
|
||||
ASDisplayNode *secondChild = ASDisplayNodeWithBackgroundColor([UIColor blueColor], (CGSize){100, 100});
|
||||
secondChild.layoutPosition = CGPointMake(0, 50);
|
||||
secondChild.style.layoutPosition = CGPointMake(0, 50);
|
||||
|
||||
[self testWithChildren:@[firstChild, secondChild] sizeRange:sizeRange identifier:identifier];
|
||||
}
|
||||
|
||||
@@ -113,11 +113,11 @@
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
// username / photo location header vertical stack
|
||||
_photoLocationLabel.flexShrink = YES;
|
||||
_userNameLabel.flexShrink = YES;
|
||||
_photoLocationLabel.style.flexShrink = YES;
|
||||
_userNameLabel.style.flexShrink = YES;
|
||||
|
||||
ASStackLayoutSpec *headerSubStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
headerSubStack.flexShrink = YES;
|
||||
headerSubStack.style.flexShrink = YES;
|
||||
if (_photoLocationLabel.attributedText) {
|
||||
[headerSubStack setChildren:@[_userNameLabel, _photoLocationLabel]];
|
||||
} else {
|
||||
@@ -127,12 +127,12 @@
|
||||
// header stack
|
||||
|
||||
// constrain avatar image frame size
|
||||
_userAvatarImageView.width = ASDimensionMakeWithPoints(USER_IMAGE_HEIGHT);
|
||||
_userAvatarImageView.height = ASDimensionMakeWithPoints(USER_IMAGE_HEIGHT);
|
||||
_photoTimeIntervalSincePostLabel.spacingBefore = HORIZONTAL_BUFFER; // to remove double spaces around spacer
|
||||
_userAvatarImageView.style.width = ASDimensionMakeWithPoints(USER_IMAGE_HEIGHT);
|
||||
_userAvatarImageView.style.height = ASDimensionMakeWithPoints(USER_IMAGE_HEIGHT);
|
||||
_photoTimeIntervalSincePostLabel.style.spacingBefore = HORIZONTAL_BUFFER; // to remove double spaces around spacer
|
||||
|
||||
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init]; // FIXME: long locations overflow post time - set max size?
|
||||
spacer.flexGrow = YES;
|
||||
spacer.style.flexGrow = YES;
|
||||
|
||||
UIEdgeInsets avatarInsets = UIEdgeInsetsMake(HORIZONTAL_BUFFER, 0, HORIZONTAL_BUFFER, HORIZONTAL_BUFFER);
|
||||
ASInsetLayoutSpec *avatarInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:avatarInsets child:_userAvatarImageView];
|
||||
@@ -159,8 +159,8 @@
|
||||
CGFloat cellWidth = constrainedSize.max.width;
|
||||
|
||||
// constrain photo frame size
|
||||
_photoImageView.width = ASDimensionMakeWithPoints(cellWidth);
|
||||
_photoImageView.height = ASDimensionMakeWithPoints(cellWidth);
|
||||
_photoImageView.style.width = ASDimensionMakeWithPoints(cellWidth);
|
||||
_photoImageView.style.height = ASDimensionMakeWithPoints(cellWidth);
|
||||
|
||||
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
|
||||
verticalStack.alignItems = ASStackLayoutAlignItemsStretch; // stretch headerStack to fill horizontal space
|
||||
|
||||
Reference in New Issue
Block a user