mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 05:26:48 +00:00
Moved ASLayoutable* properties into ASLayoutOptions class
This commit is contained in:
parent
32e2f7f1ad
commit
afade854af
@ -231,6 +231,10 @@
|
||||
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C6BB3B21B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */; };
|
||||
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.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, ); }; };
|
||||
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -577,6 +581,8 @@
|
||||
9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBaselineLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASBaselineLayoutSpec.mm; sourceTree = "<group>"; };
|
||||
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = "<group>"; };
|
||||
9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutable.h; path = AsyncDisplayKit/Layout/ASStaticLayoutable.h; sourceTree = "<group>"; };
|
||||
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutOptions.h; path = AsyncDisplayKit/Layout/ASLayoutOptions.h; sourceTree = "<group>"; };
|
||||
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASLayoutOptions.m; path = AsyncDisplayKit/Layout/ASLayoutOptions.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>"; };
|
||||
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
|
||||
@ -993,6 +999,8 @@
|
||||
ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */,
|
||||
9C3061041B857EC400D0530B /* ASBaselineLayoutSpec.h */,
|
||||
9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */,
|
||||
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */,
|
||||
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */,
|
||||
);
|
||||
name = Layout;
|
||||
path = ..;
|
||||
@ -1060,6 +1068,7 @@
|
||||
058D0A49195D05CB00B7D73C /* ASControlNode+Subclasses.h in Headers */,
|
||||
058D0A4A195D05CB00B7D73C /* ASDisplayNode.h in Headers */,
|
||||
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */,
|
||||
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */,
|
||||
058D0A4B195D05CB00B7D73C /* ASDisplayNode.mm in Headers */,
|
||||
430E7C8F1B4C23F100697A4C /* ASIndexPath.h in Headers */,
|
||||
058D0A4C195D05CB00B7D73C /* ASDisplayNode+Subclasses.h in Headers */,
|
||||
@ -1191,6 +1200,7 @@
|
||||
B35062391B010EFD0018CF92 /* ASThread.h in Headers */,
|
||||
B35062131B010EFD0018CF92 /* ASBasicImageDownloader.h in Headers */,
|
||||
34EFC7791B701D3600AD841F /* ASLayoutSpecUtilities.h in Headers */,
|
||||
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */,
|
||||
34EFC76A1B701CE600AD841F /* ASLayoutSpec.h in Headers */,
|
||||
B35062221B010EFD0018CF92 /* ASMultidimensionalArrayUtils.h in Headers */,
|
||||
B350625B1B010F070018CF92 /* ASEqualityHelpers.h in Headers */,
|
||||
@ -1451,6 +1461,7 @@
|
||||
ACF6ED2E1B17843500DA7C62 /* ASRatioLayoutSpec.mm in Sources */,
|
||||
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
|
||||
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
||||
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */,
|
||||
ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutSpec.mm in Sources */,
|
||||
058D0A2C195D050800B7D73C /* ASSentinel.m in Sources */,
|
||||
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
|
||||
@ -1577,6 +1588,7 @@
|
||||
B350621C1B010EFD0018CF92 /* ASFlowLayoutController.mm in Sources */,
|
||||
B35062231B010EFD0018CF92 /* ASMultidimensionalArrayUtils.mm in Sources */,
|
||||
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.mm in Sources */,
|
||||
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */,
|
||||
B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */,
|
||||
B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */,
|
||||
B35061F91B010EFD0018CF92 /* ASControlNode.m in Sources */,
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASStackLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
|
||||
/**
|
||||
* UIView creation block. Used to create the backing view of a new display node.
|
||||
@ -40,7 +40,7 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
|
||||
*
|
||||
*/
|
||||
|
||||
@interface ASDisplayNode : ASDealloc2MainObject <ASStackLayoutable>
|
||||
@interface ASDisplayNode : ASDealloc2MainObject <ASLayoutable>
|
||||
|
||||
|
||||
/** @name Initializing a node object */
|
||||
|
||||
@ -41,12 +41,6 @@
|
||||
|
||||
@implementation ASDisplayNode
|
||||
|
||||
@synthesize spacingBefore = _spacingBefore;
|
||||
@synthesize spacingAfter = _spacingAfter;
|
||||
@synthesize flexGrow = _flexGrow;
|
||||
@synthesize flexShrink = _flexShrink;
|
||||
@synthesize flexBasis = _flexBasis;
|
||||
@synthesize alignSelf = _alignSelf;
|
||||
@synthesize preferredFrameSize = _preferredFrameSize;
|
||||
|
||||
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
|
||||
@ -155,7 +149,6 @@ void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)
|
||||
}
|
||||
_methodOverrides = overrides;
|
||||
|
||||
_flexBasis = ASRelativeDimensionUnconstrained;
|
||||
_preferredFrameSize = CGSizeZero;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#import <AsyncDisplayKit/ASControlNode.h>
|
||||
#import <AsyncDisplayKit/ASBaselineLayoutable.h>
|
||||
|
||||
@protocol ASTextNodeDelegate;
|
||||
|
||||
@ -30,7 +29,7 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
@abstract Draws interactive rich text.
|
||||
@discussion Backed by TextKit.
|
||||
*/
|
||||
@interface ASTextNode : ASControlNode <ASBaselineLayoutable>
|
||||
@interface ASTextNode : ASControlNode
|
||||
|
||||
/**
|
||||
@abstract The attributed string to show.
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#import <AsyncDisplayKit/ASTextNodeTextKitHelpers.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASTextNodeRenderer.h"
|
||||
#import "ASTextNodeShadower.h"
|
||||
|
||||
@ -108,9 +107,6 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
|
||||
UILongPressGestureRecognizer *_longPressGestureRecognizer;
|
||||
}
|
||||
|
||||
@synthesize ascender = _ascender;
|
||||
@synthesize descender = _descender;
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (instancetype)init
|
||||
@ -359,9 +355,6 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
|
||||
self.isAccessibilityElement = YES;
|
||||
}
|
||||
});
|
||||
|
||||
_ascender = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * ASScreenScale())/ASScreenScale();
|
||||
_descender = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * ASScreenScale())/ASScreenScale();
|
||||
}
|
||||
|
||||
#pragma mark - Text Layout
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#import <AsyncDisplayKit/ASStackLayoutSpec.h>
|
||||
#import <AsyncDisplayKit/ASBaselineLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ASBaselineLayoutBaselineAlignment) {
|
||||
/** No baseline alignment. This is only valid for a vertical stack */
|
||||
@ -29,7 +29,7 @@ typedef NS_ENUM(NSUInteger, ASBaselineLayoutBaselineAlignment) {
|
||||
If the spec is created with a vertical direction, a child's vertical spacing will be measured from its
|
||||
baseline instead of from the child's bounding box.
|
||||
*/
|
||||
@interface ASBaselineLayoutSpec : ASLayoutSpec <ASBaselineLayoutable>
|
||||
@interface ASBaselineLayoutSpec : ASLayoutSpec
|
||||
|
||||
/** Specifies the direction children are stacked in. */
|
||||
@property (nonatomic, assign) ASStackLayoutDirection direction;
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#import "ASBaselineLayoutSpec.h"
|
||||
#import "ASStackLayoutable.h"
|
||||
|
||||
#import <numeric>
|
||||
#import <vector>
|
||||
@ -26,12 +25,6 @@
|
||||
|
||||
|
||||
@implementation ASBaselineLayoutSpec
|
||||
{
|
||||
ASDN::RecursiveMutex _propertyLock;
|
||||
}
|
||||
|
||||
@synthesize ascender = _ascender;
|
||||
@synthesize descender = _descender;
|
||||
|
||||
- (instancetype)initWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing baselineAlignment:(ASBaselineLayoutBaselineAlignment)baselineAlignment justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray *)children
|
||||
{
|
||||
@ -61,8 +54,8 @@
|
||||
ASStackLayoutSpecStyle stackStyle = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems};
|
||||
ASBaselineLayoutSpecStyle style = { .baselineAlignment = _baselineAlignment, .stackLayoutStyle = stackStyle };
|
||||
|
||||
std::vector<id<ASStackLayoutable>> stackChildren = std::vector<id<ASStackLayoutable>>();
|
||||
for (id<ASStackLayoutable> child in self.children) {
|
||||
std::vector<id<ASLayoutable>> stackChildren = std::vector<id<ASLayoutable>>();
|
||||
for (id<ASLayoutable> child in self.children) {
|
||||
stackChildren.push_back(child);
|
||||
}
|
||||
|
||||
@ -74,25 +67,11 @@
|
||||
|
||||
NSArray *sublayouts = [NSArray arrayWithObjects:&baselinePositionedLayout.sublayouts[0] count:baselinePositionedLayout.sublayouts.size()];
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_ascender = baselinePositionedLayout.ascender;
|
||||
_descender = baselinePositionedLayout.descender;
|
||||
|
||||
return [ASLayout layoutWithLayoutableObject:self
|
||||
size:ASSizeRangeClamp(constrainedSize, finalSize)
|
||||
sublayouts:sublayouts];
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
{
|
||||
[super setChildren:children];
|
||||
#if DEBUG
|
||||
for (id<ASBaselineLayoutable> child in children) {
|
||||
NSAssert(([child finalLayoutable] == child && [child conformsToProtocol:@protocol(ASBaselineLayoutable)]) || ([child finalLayoutable] != child && [[child finalLayoutable] conformsToProtocol:@protocol(ASBaselineLayoutable)]), @"child must conform to ASBaselineLayoutable");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"ASBaselineLayoutSpec only supports setChildren");
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "ASStackLayoutable.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol ASBaselineLayoutable <ASStackLayoutable>
|
||||
@protocol ASBaselineLayoutable
|
||||
|
||||
/**
|
||||
* @abstract The distance from the top of the layoutable object to its baseline
|
||||
|
||||
49
AsyncDisplayKit/Layout/ASLayoutOptions.h
Normal file
49
AsyncDisplayKit/Layout/ASLayoutOptions.h
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// ASLayoutOptions.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Ricky Cancro on 8/27/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol ASLayoutable;
|
||||
|
||||
#import <AsyncDisplayKit/ASBaselineLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASStackLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASStaticLayoutable.h>
|
||||
|
||||
@interface ASLayoutOptions : NSObject <ASBaselineLayoutable, ASStackLayoutable, ASStaticLayoutable, NSCopying>
|
||||
|
||||
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable;
|
||||
- (void)setValuesFromLayoutable:(id<ASLayoutable>)layoutable;
|
||||
|
||||
@property (nonatomic, assign) BOOL isMutable;
|
||||
|
||||
#if DEBUG
|
||||
@property (nonatomic, assign) NSUInteger changeMonitor;
|
||||
#endif
|
||||
|
||||
#pragma mark - ASStackLayoutable
|
||||
|
||||
@property (nonatomic, readwrite) CGFloat spacingBefore;
|
||||
@property (nonatomic, readwrite) CGFloat spacingAfter;
|
||||
@property (nonatomic, readwrite) BOOL flexGrow;
|
||||
@property (nonatomic, readwrite) BOOL flexShrink;
|
||||
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
|
||||
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
|
||||
|
||||
#pragma mark - ASBaselineLayoutable
|
||||
|
||||
@property (nonatomic, readwrite) CGFloat ascender;
|
||||
@property (nonatomic, readwrite) CGFloat descender;
|
||||
|
||||
#pragma mark - ASStaticLayoutable
|
||||
|
||||
@property (nonatomic, readwrite) ASRelativeSizeRange sizeRange;
|
||||
@property (nonatomic, readwrite) CGPoint position;
|
||||
|
||||
- (void)setupDefaults;
|
||||
|
||||
@end
|
||||
120
AsyncDisplayKit/Layout/ASLayoutOptions.m
Normal file
120
AsyncDisplayKit/Layout/ASLayoutOptions.m
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// ASLayoutOptions.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Ricky Cancro on 8/27/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ASLayoutOptions.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASTextNode.h>
|
||||
#import "ASInternalHelpers.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation ASLayoutOptions
|
||||
|
||||
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable;
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self setupDefaults];
|
||||
[self setValuesFromLayoutable:layoutable];
|
||||
#if DEBUG
|
||||
[self addObserver:self forKeyPath:@"changeMonitor"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:nil];
|
||||
#endif
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
+ (NSSet *)keyPathsForValuesAffectingChangeMonitor
|
||||
{
|
||||
NSMutableSet *keys = [NSMutableSet set];
|
||||
unsigned int count;
|
||||
|
||||
objc_property_t *properties = class_copyPropertyList([self class], &count);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
NSString *property = [NSString stringWithCString:property_getName(properties[i]) encoding:NSASCIIStringEncoding];
|
||||
|
||||
if ([property isEqualToString: @"observableSelf"] == NO) {
|
||||
[keys addObject: property];
|
||||
}
|
||||
}
|
||||
free(properties);
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
#if DEBUG
|
||||
if ([keyPath isEqualToString:@"changeMonitor"]) {
|
||||
ASDisplayNodeAssert(self.isMutable, @"You cannot alter this class once it is marked as immutable");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - NSCopying
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
ASLayoutOptions *copy = [[[self class] alloc] init];
|
||||
|
||||
copy.flexBasis = self.flexBasis;
|
||||
copy.spacingAfter = self.spacingAfter;
|
||||
copy.spacingBefore = self.spacingBefore;
|
||||
copy.flexGrow = self.flexGrow;
|
||||
copy.flexShrink = self.flexShrink;
|
||||
|
||||
copy.ascender = self.ascender;
|
||||
copy.descender = self.descender;
|
||||
|
||||
copy.sizeRange = self.sizeRange;
|
||||
copy.position = self.position;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#pragma mark - Defaults
|
||||
- (void)setupDefaults
|
||||
{
|
||||
_flexBasis = ASRelativeDimensionUnconstrained;
|
||||
_spacingBefore = 0;
|
||||
_spacingAfter = 0;
|
||||
_flexGrow = NO;
|
||||
_flexShrink = NO;
|
||||
_alignSelf = ASStackLayoutAlignSelfAuto;
|
||||
|
||||
_ascender = 0;
|
||||
_descender = 0;
|
||||
|
||||
_sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero));
|
||||
_position = CGPointZero;
|
||||
}
|
||||
|
||||
// Do this here instead of in Node/Spec subclasses so that custom specs can set default values
|
||||
- (void)setValuesFromLayoutable:(id<ASLayoutable>)layoutable
|
||||
{
|
||||
if ([layoutable isKindOfClass:[ASTextNode class]]) {
|
||||
ASTextNode *textNode = (ASTextNode *)layoutable;
|
||||
self.ascender = round([[textNode.attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * ASScreenScale())/ASScreenScale();
|
||||
self.descender = round([[textNode.attributedString attribute:NSFontAttributeName atIndex:textNode.attributedString.length - 1 effectiveRange:NULL] descender] * ASScreenScale())/ASScreenScale();
|
||||
}
|
||||
if ([layoutable isKindOfClass:[ASDisplayNode class]]) {
|
||||
ASDisplayNode *displayNode = (ASDisplayNode *)layoutable;
|
||||
self.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize), ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize));
|
||||
self.position = displayNode.frame.origin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@ -8,10 +8,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#import <AsyncDisplayKit/ASStackLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
|
||||
/** A layout spec is an immutable object that describes a layout, loosely inspired by React. */
|
||||
@interface ASLayoutSpec : NSObject <ASStackLayoutable>
|
||||
@interface ASLayoutSpec : NSObject <ASLayoutable>
|
||||
|
||||
/**
|
||||
Creation of a layout spec should only happen by a user in layoutSpecThatFits:. During that method, a
|
||||
@ -23,12 +23,15 @@
|
||||
- (instancetype)init;
|
||||
|
||||
- (void)setChild:(id<ASLayoutable>)child;
|
||||
- (id<ASLayoutable>)child;
|
||||
|
||||
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier;
|
||||
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier;
|
||||
|
||||
- (void)setChildren:(NSArray *)children;
|
||||
|
||||
- (id<ASLayoutable>)child;
|
||||
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier;
|
||||
- (NSArray *)children;
|
||||
|
||||
+ (ASLayoutOptions *)layoutOptionsForChild:(id<ASLayoutable>)child;
|
||||
+ (void)associateLayoutOptions:(ASLayoutOptions *)layoutOptions withChild:(id<ASLayoutable>)child;
|
||||
+ (void)setLayoutOptionsClass:(Class)layoutOptionsClass;
|
||||
|
||||
@end
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASLayout.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static NSString * const kDefaultChildKey = @"kDefaultChildKey";
|
||||
static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
|
||||
@ -25,12 +27,6 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
|
||||
@implementation ASLayoutSpec
|
||||
|
||||
@synthesize spacingBefore = _spacingBefore;
|
||||
@synthesize spacingAfter = _spacingAfter;
|
||||
@synthesize flexGrow = _flexGrow;
|
||||
@synthesize flexShrink = _flexShrink;
|
||||
@synthesize flexBasis = _flexBasis;
|
||||
@synthesize alignSelf = _alignSelf;
|
||||
@synthesize layoutChildren = _layoutChildren;
|
||||
|
||||
- (instancetype)init
|
||||
@ -39,7 +35,6 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
return nil;
|
||||
}
|
||||
_layoutChildren = [NSMutableDictionary dictionary];
|
||||
_flexBasis = ASRelativeDimensionUnconstrained;
|
||||
_isMutable = YES;
|
||||
return self;
|
||||
}
|
||||
@ -61,15 +56,34 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
[self setChild:child forIdentifier:kDefaultChildKey];
|
||||
}
|
||||
|
||||
- (id<ASLayoutable>)child
|
||||
{
|
||||
return self.layoutChildren[kDefaultChildKey];
|
||||
}
|
||||
|
||||
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
|
||||
{
|
||||
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
|
||||
self.layoutChildren[identifier] = [child finalLayoutable];
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
layoutOptions.isMutable = NO;
|
||||
self.layoutChildren[identifier] = child;
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
{
|
||||
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
|
||||
|
||||
NSMutableArray *finalChildren = [NSMutableArray arrayWithCapacity:children.count];
|
||||
for (id<ASLayoutable> child in children) {
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
|
||||
layoutOptions.isMutable = NO;
|
||||
|
||||
if (finalLayoutable != child) {
|
||||
ASLayoutOptions *finalLayoutOptions = [layoutOptions copy];
|
||||
finalLayoutOptions.isMutable = NO;
|
||||
[ASLayoutSpec associateLayoutOptions:finalLayoutOptions withChild:finalLayoutable];
|
||||
}
|
||||
|
||||
[finalChildren addObject:finalLayoutable];
|
||||
}
|
||||
|
||||
self.layoutChildren[kDefaultChildrenKey] = [NSArray arrayWithArray:finalChildren];
|
||||
}
|
||||
|
||||
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier
|
||||
@ -77,14 +91,9 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
return self.layoutChildren[identifier];
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
- (id<ASLayoutable>)child
|
||||
{
|
||||
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
|
||||
NSMutableArray *finalChildren = [NSMutableArray arrayWithCapacity:children.count];
|
||||
for (id<ASLayoutable> child in children) {
|
||||
[finalChildren addObject:[child finalLayoutable]];
|
||||
}
|
||||
self.layoutChildren[kDefaultChildrenKey] = [NSArray arrayWithArray:finalChildren];
|
||||
return self.layoutChildren[kDefaultChildKey];
|
||||
}
|
||||
|
||||
- (NSArray *)children
|
||||
@ -92,4 +101,35 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
||||
return self.layoutChildren[kDefaultChildrenKey];
|
||||
}
|
||||
|
||||
static Class gLayoutOptionsClass = [ASLayoutOptions class];
|
||||
+ (void)setLayoutOptionsClass:(Class)layoutOptionsClass
|
||||
{
|
||||
gLayoutOptionsClass = layoutOptionsClass;
|
||||
}
|
||||
|
||||
+ (ASLayoutOptions *)optionsForChild:(id<ASLayoutable>)child
|
||||
{
|
||||
ASLayoutOptions *layoutOptions = [[gLayoutOptionsClass alloc] init];;
|
||||
[layoutOptions setValuesFromLayoutable:child];
|
||||
layoutOptions.isMutable = NO;
|
||||
return layoutOptions;
|
||||
}
|
||||
|
||||
+ (void)associateLayoutOptions:(ASLayoutOptions *)layoutOptions withChild:(id<ASLayoutable>)child
|
||||
{
|
||||
objc_setAssociatedObject(child, @selector(setChild:), layoutOptions, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (ASLayoutOptions *)layoutOptionsForChild:(id<ASLayoutable>)child
|
||||
{
|
||||
ASLayoutOptions *layoutOptions = objc_getAssociatedObject(child, @selector(setChild:));
|
||||
if (layoutOptions == nil) {
|
||||
layoutOptions = [self optionsForChild:child];
|
||||
[self associateLayoutOptions:layoutOptions withChild:child];
|
||||
}
|
||||
return objc_getAssociatedObject(child, @selector(setChild:));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASStackLayoutDefines.h>
|
||||
#import <AsyncDisplayKit/ASLayoutOptions.h>
|
||||
|
||||
@class ASLayout;
|
||||
@class ASLayoutSpec;
|
||||
|
||||
@ -72,17 +72,6 @@
|
||||
_spacing = spacing;
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
{
|
||||
[super setChildren:children];
|
||||
|
||||
#if DEBUG
|
||||
for (id<ASStackLayoutable> child in children) {
|
||||
ASDisplayNodeAssert(([child finalLayoutable] == child && [child conformsToProtocol:@protocol(ASStackLayoutable)]) || ([child finalLayoutable] != child && [[child finalLayoutable] conformsToProtocol:@protocol(ASStackLayoutable)]), @"child must conform to ASBaselineLayoutable");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"ASStackLayoutSpec only supports setChildren");
|
||||
@ -91,9 +80,8 @@
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||
{
|
||||
ASStackLayoutSpecStyle style = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems};
|
||||
std::vector<id<ASStackLayoutable>> stackChildren = std::vector<id<ASStackLayoutable>>();
|
||||
for (id<ASStackLayoutable> child in self.children) {
|
||||
NSAssert([child conformsToProtocol:@protocol(ASStackLayoutable)], @"Child must implement ASStackLayoutable");
|
||||
std::vector<id<ASLayoutable>> stackChildren = std::vector<id<ASLayoutable>>();
|
||||
for (id<ASLayoutable> child in self.children) {
|
||||
stackChildren.push_back(child);
|
||||
}
|
||||
|
||||
|
||||
@ -8,9 +8,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASStackLayoutDefines.h>
|
||||
|
||||
@protocol ASStackLayoutable <ASLayoutable>
|
||||
@protocol ASStackLayoutable <NSObject>
|
||||
|
||||
/**
|
||||
* @abstract Additional space to place before this object in the stacking direction.
|
||||
|
||||
@ -31,17 +31,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setChildren:(NSArray *)children
|
||||
{
|
||||
[super setChildren:children];
|
||||
|
||||
#if DEBUG
|
||||
for (id<ASStaticLayoutable> child in children) {
|
||||
ASDisplayNodeAssert(([child finalLayoutable] == child && [child conformsToProtocol:@protocol(ASStaticLayoutable)]) || ([child finalLayoutable] != child && [[child finalLayoutable] conformsToProtocol:@protocol(ASStaticLayoutable)]), @"child must conform to ASStaticLayoutable");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||
{
|
||||
CGSize size = {
|
||||
@ -50,16 +39,17 @@
|
||||
};
|
||||
|
||||
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:self.children.count];
|
||||
for (id<ASStaticLayoutable> child in self.children) {
|
||||
for (id<ASLayoutable> child in self.children) {
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
CGSize autoMaxSize = {
|
||||
constrainedSize.max.width - child.position.x,
|
||||
constrainedSize.max.height - child.position.y
|
||||
constrainedSize.max.width - layoutOptions.position.x,
|
||||
constrainedSize.max.height - layoutOptions.position.y
|
||||
};
|
||||
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, child.sizeRange)
|
||||
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, layoutOptions.sizeRange)
|
||||
? ASSizeRangeMake({0, 0}, autoMaxSize)
|
||||
: ASRelativeSizeRangeResolve(child.sizeRange, size);
|
||||
: ASRelativeSizeRangeResolve(layoutOptions.sizeRange, size);
|
||||
ASLayout *sublayout = [child measureWithSizeRange:childConstraint];
|
||||
sublayout.position = child.position;
|
||||
sublayout.position = layoutOptions.position;
|
||||
[sublayouts addObject:sublayout];
|
||||
}
|
||||
|
||||
|
||||
@ -8,10 +8,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
#import <AsyncDisplayKit/ASRelativeSize.h>
|
||||
|
||||
@protocol ASStaticLayoutable<ASLayoutable>
|
||||
@protocol ASStaticLayoutable
|
||||
|
||||
/**
|
||||
If specified, the child's size is restricted according to this size. Percentages are resolved relative to the static layout spec.
|
||||
|
||||
@ -15,15 +15,14 @@
|
||||
|
||||
static CGFloat baselineForItem(const ASBaselineLayoutSpecStyle &style,
|
||||
const ASLayout *layout) {
|
||||
|
||||
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>) layout.layoutableObject;
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:layout.layoutableObject];
|
||||
switch (style.baselineAlignment) {
|
||||
case ASBaselineLayoutBaselineAlignmentNone:
|
||||
return 0;
|
||||
case ASBaselineLayoutBaselineAlignmentFirst:
|
||||
return child.ascender;
|
||||
return layoutOptions.ascender;
|
||||
case ASBaselineLayoutBaselineAlignmentLast:
|
||||
return layout.size.height + child.descender;
|
||||
return layout.size.height + layoutOptions.descender;
|
||||
}
|
||||
|
||||
}
|
||||
@ -34,10 +33,10 @@ static CGFloat baselineOffset(const ASBaselineLayoutSpecStyle &style,
|
||||
const CGFloat maxBaseline)
|
||||
{
|
||||
if (style.stackLayoutStyle.direction == ASStackLayoutDirectionHorizontal) {
|
||||
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>)l.layoutableObject;
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.layoutableObject];
|
||||
switch (style.baselineAlignment) {
|
||||
case ASBaselineLayoutBaselineAlignmentFirst:
|
||||
return maxAscender - child.ascender;
|
||||
return maxAscender - layoutOptions.ascender;
|
||||
case ASBaselineLayoutBaselineAlignmentLast:
|
||||
return maxBaseline - baselineForItem(style, l);
|
||||
case ASBaselineLayoutBaselineAlignmentNone:
|
||||
@ -91,9 +90,11 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
|
||||
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 ((id<ASBaselineLayoutable>)a.layoutableObject).ascender < ((id<ASBaselineLayoutable>)b.layoutableObject).ascender;
|
||||
ASLayoutOptions *layoutOptionsA = [ASLayoutSpec layoutOptionsForChild:a.layoutableObject];
|
||||
ASLayoutOptions *layoutOptionsB = [ASLayoutSpec layoutOptionsForChild:b.layoutableObject];
|
||||
return layoutOptionsA.ascender < layoutOptionsB.ascender;
|
||||
});
|
||||
const CGFloat maxAscender = baselineIt == positionedLayout.sublayouts.end() ? 0 : ((id<ASBaselineLayoutable>)(*ascenderIt).layoutableObject).ascender;
|
||||
const CGFloat maxAscender = baselineIt == positionedLayout.sublayouts.end() ? 0 : [ASLayoutSpec layoutOptionsForChild:(*ascenderIt).layoutableObject].ascender;
|
||||
|
||||
/*
|
||||
Step 3: Take each child and update its layout position based on the baseline offset.
|
||||
@ -106,8 +107,8 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
|
||||
CGPoint p = CGPointZero;
|
||||
BOOL first = YES;
|
||||
auto stackedChildren = AS::map(positionedLayout.sublayouts, [&](ASLayout *l) -> ASLayout *{
|
||||
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>) l.layoutableObject;
|
||||
p = p + directionPoint(stackStyle.direction, child.spacingBefore, 0);
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.layoutableObject];
|
||||
p = p + directionPoint(stackStyle.direction, layoutOptions.spacingBefore, 0);
|
||||
if (first) {
|
||||
// if this is the first item use the previously computed start point
|
||||
p = l.position;
|
||||
@ -124,9 +125,9 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
|
||||
// node from baselines and not bounding boxes.
|
||||
CGFloat spacingAfterBaseline = 0;
|
||||
if (stackStyle.direction == ASStackLayoutDirectionVertical) {
|
||||
spacingAfterBaseline = child.descender;
|
||||
spacingAfterBaseline = layoutOptions.descender;
|
||||
}
|
||||
p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + child.spacingAfter + spacingAfterBaseline, 0);
|
||||
p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + layoutOptions.spacingAfter + spacingAfterBaseline, 0);
|
||||
|
||||
return l;
|
||||
});
|
||||
@ -151,12 +152,12 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
|
||||
|
||||
/*
|
||||
Step 5: finally, we must find the smallest descender (descender is negative). This is since ASBaselineLayoutSpec implements
|
||||
ASBaselineLayoutable and needs an ascender and descender to lay itself out properly.
|
||||
ASLayoutable and needs an ascender and descender to lay itself out properly.
|
||||
*/
|
||||
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 : ((id<ASBaselineLayoutable>)(*descenderIt).layoutableObject).descender;
|
||||
const CGFloat minDescender = descenderIt == stackedChildren.end() ? 0 : [ASLayoutSpec layoutOptionsForChild:(*descenderIt).layoutableObject].descender;
|
||||
|
||||
return {stackedChildren, crossSize, maxAscender, minDescender};
|
||||
}
|
||||
|
||||
@ -19,7 +19,8 @@ static CGFloat crossOffset(const ASStackLayoutSpecStyle &style,
|
||||
const ASStackUnpositionedItem &l,
|
||||
const CGFloat crossSize)
|
||||
{
|
||||
switch (alignment(l.child.alignSelf, style.alignItems)) {
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
|
||||
switch (alignment(layoutOptions.alignSelf, style.alignItems)) {
|
||||
case ASStackLayoutAlignItemsEnd:
|
||||
return crossSize - crossDimension(style.direction, l.layout.size);
|
||||
case ASStackLayoutAlignItemsCenter:
|
||||
@ -48,14 +49,15 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
|
||||
CGPoint p = directionPoint(style.direction, offset, 0);
|
||||
BOOL first = YES;
|
||||
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayout *{
|
||||
p = p + directionPoint(style.direction, l.child.spacingBefore, 0);
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
|
||||
p = p + directionPoint(style.direction, layoutOptions.spacingBefore, 0);
|
||||
if (!first) {
|
||||
p = p + directionPoint(style.direction, style.spacing, 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) + layoutOptions.spacingAfter, 0);
|
||||
return l.layout;
|
||||
});
|
||||
return {stackedChildren, crossSize};
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
struct ASStackUnpositionedItem {
|
||||
/** The original source child. */
|
||||
id<ASStackLayoutable> child;
|
||||
id<ASLayoutable> child;
|
||||
/** The proposed layout. */
|
||||
ASLayout *layout;
|
||||
};
|
||||
@ -31,7 +31,7 @@ struct ASStackUnpositionedLayout {
|
||||
const CGFloat violation;
|
||||
|
||||
/** Given a set of children, computes the unpositioned layouts for those children. */
|
||||
static ASStackUnpositionedLayout compute(const std::vector<id<ASStackLayoutable>> &children,
|
||||
static ASStackUnpositionedLayout compute(const std::vector<id<ASLayoutable>> &children,
|
||||
const ASStackLayoutSpecStyle &style,
|
||||
const ASSizeRange &sizeRange);
|
||||
};
|
||||
|
||||
@ -18,14 +18,15 @@
|
||||
/**
|
||||
Sizes the child given the parameters specified, and returns the computed layout.
|
||||
*/
|
||||
static ASLayout *crossChildLayout(const id<ASStackLayoutable> child,
|
||||
static ASLayout *crossChildLayout(const id<ASLayoutable> child,
|
||||
const ASStackLayoutSpecStyle style,
|
||||
const CGFloat stackMin,
|
||||
const CGFloat stackMax,
|
||||
const CGFloat crossMin,
|
||||
const CGFloat crossMax)
|
||||
{
|
||||
const ASStackLayoutAlignItems alignItems = alignment(child.alignSelf, style.alignItems);
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
const ASStackLayoutAlignItems alignItems = alignment(layoutOptions.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);
|
||||
@ -75,7 +76,8 @@ 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);
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
|
||||
const ASStackLayoutAlignItems alignItems = alignment(layoutOptions.alignSelf, style.alignItems);
|
||||
|
||||
const CGFloat cross = crossDimension(style.direction, l.layout.size);
|
||||
const CGFloat stack = stackDimension(style.direction, l.layout.size);
|
||||
@ -111,7 +113,8 @@ static CGFloat computeStackDimensionSum(const std::vector<ASStackUnpositionedIte
|
||||
// Start from default spacing between each child:
|
||||
children.empty() ? 0 : style.spacing * (children.size() - 1),
|
||||
[&](CGFloat x, const ASStackUnpositionedItem &l) {
|
||||
return x + l.child.spacingBefore + l.child.spacingAfter;
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
|
||||
return x + layoutOptions.spacingBefore + layoutOptions.spacingAfter;
|
||||
});
|
||||
|
||||
// Sum up the childrens' dimensions (including spacing) in the stack direction.
|
||||
@ -180,22 +183,23 @@ static std::function<BOOL(const ASStackUnpositionedItem &)> isFlexibleInViolatio
|
||||
if (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 [ASLayoutSpec layoutOptionsForChild:l.child].flexGrow; };
|
||||
} else {
|
||||
return [](const ASStackUnpositionedItem &l) { return l.child.flexShrink; };
|
||||
return [](const ASStackUnpositionedItem &l) { return [ASLayoutSpec layoutOptionsForChild:l.child].flexShrink; };
|
||||
}
|
||||
}
|
||||
|
||||
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASStackLayoutable> child)
|
||||
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
|
||||
{
|
||||
return child.flexGrow && child.flexShrink;
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
return layoutOptions.flexGrow && layoutOptions.flexShrink;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASStackLayoutable>> &children,
|
||||
ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASLayoutable>> &children,
|
||||
const ASStackLayoutSpecStyle &style,
|
||||
const ASSizeRange &sizeRange)
|
||||
{
|
||||
@ -283,7 +287,7 @@ static void flexChildrenAlongStackDimension(std::vector<ASStackUnpositionedItem>
|
||||
Performs the first unconstrained layout of the children, generating the unpositioned items that are then flexed and
|
||||
stretched.
|
||||
*/
|
||||
static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASStackLayoutable>> &children,
|
||||
static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASLayoutable>> &children,
|
||||
const ASStackLayoutSpecStyle &style,
|
||||
const ASSizeRange &sizeRange,
|
||||
const CGSize size,
|
||||
@ -292,9 +296,10 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
|
||||
const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min);
|
||||
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
|
||||
|
||||
return AS::map(children, [&](id<ASStackLayoutable> child) -> ASStackUnpositionedItem {
|
||||
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, child.flexBasis);
|
||||
const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.flexBasis, stackDimension(style.direction, size));
|
||||
return AS::map(children, [&](id<ASLayoutable> child) -> ASStackUnpositionedItem {
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
|
||||
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, layoutOptions.flexBasis);
|
||||
const CGFloat exactStackDimension = ASRelativeDimensionResolve(layoutOptions.flexBasis, stackDimension(style.direction, size));
|
||||
|
||||
if (useOptimizedFlexing && isFlexibleInBothDirections(child)) {
|
||||
return { child, [ASLayout layoutWithLayoutableObject:child size:{0, 0}] };
|
||||
@ -312,7 +317,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
|
||||
});
|
||||
}
|
||||
|
||||
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASStackLayoutable>> &children,
|
||||
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASLayoutable>> &children,
|
||||
const ASStackLayoutSpecStyle &style,
|
||||
const ASSizeRange &sizeRange)
|
||||
{
|
||||
|
||||
@ -94,7 +94,7 @@ static NSString *suffixForCenteringOptions(ASCenterLayoutSpecCenteringOptions ce
|
||||
ASDisplayNode *backgroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
|
||||
ASStaticSizeDisplayNode *foregroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
|
||||
foregroundNode.staticSize = {10, 10};
|
||||
foregroundNode.flexGrow = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:foregroundNode].flexGrow = YES;
|
||||
|
||||
ASCenterLayoutSpec *layoutSpec =
|
||||
[ASCenterLayoutSpec
|
||||
|
||||
@ -41,8 +41,8 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
];
|
||||
for (ASStaticSizeDisplayNode *subnode in subnodes) {
|
||||
subnode.staticSize = subnodeSize;
|
||||
subnode.flexGrow = flex;
|
||||
subnode.flexShrink = flex;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode].flexGrow = flex;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode].flexShrink = flex;
|
||||
}
|
||||
return subnodes;
|
||||
}
|
||||
@ -114,7 +114,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
ASStackLayoutSpecStyle style = {.direction = ASStackLayoutDirectionHorizontal};
|
||||
|
||||
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
|
||||
((ASDisplayNode *)subnodes[1]).flexShrink = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASDisplayNode *)subnodes[1])].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}};
|
||||
@ -204,23 +204,25 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 10;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 20;
|
||||
ASLayoutOptions *layoutOptions1 = [ASLayoutSpec layoutOptionsForChild:subnodes[1]];
|
||||
ASLayoutOptions *layoutOptions2 = [ASLayoutSpec layoutOptionsForChild:subnodes[2]];
|
||||
layoutOptions1.spacingBefore = 10;
|
||||
layoutOptions2.spacingBefore = 20;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBefore"];
|
||||
// Reset above spacing values
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 0;
|
||||
layoutOptions1.spacingBefore = 0;
|
||||
layoutOptions2.spacingBefore = 0;
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingAfter = 10;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingAfter = 20;
|
||||
layoutOptions1.spacingAfter = 10;
|
||||
layoutOptions2.spacingAfter = 20;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingAfter"];
|
||||
// Reset above spacing values
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingAfter = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingAfter = 0;
|
||||
layoutOptions1.spacingAfter = 0;
|
||||
layoutOptions2.spacingAfter = 0;
|
||||
|
||||
style.spacing = 10;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = -10;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingAfter = -10;
|
||||
layoutOptions1.spacingBefore = -10;
|
||||
layoutOptions2.spacingAfter = -10;
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBalancedOut"];
|
||||
}
|
||||
|
||||
@ -236,9 +238,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
// width 0-300px; height 300px
|
||||
static ASSizeRange kVariableHeight = {{0, 300}, {300, 300}};
|
||||
@ -254,9 +256,10 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
subnode2.staticSize = {50, 50};
|
||||
|
||||
ASRatioLayoutSpec *child1 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.5 child:subnode1];
|
||||
child1.flexBasis = ASRelativeDimensionMakeWithPercent(1);
|
||||
child1.flexGrow = YES;
|
||||
child1.flexShrink = YES;
|
||||
ASLayoutOptions *layoutOptions1 = [ASLayoutSpec layoutOptionsForChild:child1];
|
||||
layoutOptions1.flexBasis = ASRelativeDimensionMakeWithPercent(1);
|
||||
layoutOptions1.flexGrow = YES;
|
||||
layoutOptions1.flexShrink = YES;
|
||||
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
|
||||
[self testStackLayoutSpecWithStyle:style children:@[child1, subnode2] sizeRange:kFixedWidth subnodes:@[subnode1, subnode2] identifier:nil];
|
||||
@ -271,11 +274,11 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
|
||||
ASStaticSizeDisplayNode *subnode1 = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
|
||||
subnode1.staticSize = {100, 100};
|
||||
subnode1.flexShrink = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode1].flexShrink = YES;
|
||||
|
||||
ASStaticSizeDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor]);
|
||||
subnode2.staticSize = {50, 50};
|
||||
subnode2.flexShrink = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode2].flexShrink = YES;
|
||||
|
||||
NSArray *subnodes = @[subnode1, subnode2];
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, 100}};
|
||||
@ -291,7 +294,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
|
||||
ASStaticSizeDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor]);
|
||||
subnode2.staticSize = {50, 50};
|
||||
subnode2.alignSelf = ASStackLayoutAlignSelfCenter;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode2].alignSelf = ASStackLayoutAlignSelfCenter;
|
||||
|
||||
NSArray *subnodes = @[subnode1, subnode2];
|
||||
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
|
||||
@ -311,9 +314,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@ -332,9 +335,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@ -353,9 +356,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
|
||||
@ -374,9 +377,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kVariableSize = {{200, 200}, {300, 300}};
|
||||
// all children should be 200px wide
|
||||
@ -396,9 +399,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).spacingBefore = 0;
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).spacingBefore = 20;
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).spacingBefore = 30;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
|
||||
|
||||
static ASSizeRange kVariableSize = {{50, 50}, {300, 300}};
|
||||
// all children should be 150px wide
|
||||
@ -419,8 +422,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {150, 150};
|
||||
|
||||
for (ASStaticSizeDisplayNode *subnode in subnodes) {
|
||||
subnode.flexGrow = YES;
|
||||
subnode.flexBasis = ASRelativeDimensionMakeWithPoints(10);
|
||||
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:subnode];
|
||||
layoutOptions.flexGrow = YES;
|
||||
layoutOptions.flexBasis = ASRelativeDimensionMakeWithPoints(10);
|
||||
}
|
||||
|
||||
// width 300px; height 0-150px.
|
||||
@ -439,12 +443,12 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
|
||||
|
||||
for (ASStaticSizeDisplayNode *subnode in subnodes) {
|
||||
subnode.flexGrow = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode].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.
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).flexBasis = ASRelativeDimensionMakeWithPercent(0.5);
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].flexBasis = ASRelativeDimensionMakeWithPercent(0.5);
|
||||
|
||||
static ASSizeRange kSize = {{200, 0}, {200, INFINITY}};
|
||||
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
|
||||
@ -460,7 +464,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {50, 50};
|
||||
|
||||
for (ASStaticSizeDisplayNode *subnode in subnodes) {
|
||||
subnode.flexBasis = ASRelativeDimensionMakeWithPoints(20);
|
||||
[ASLayoutSpec layoutOptionsForChild:subnode].flexBasis = ASRelativeDimensionMakeWithPoints(20);
|
||||
}
|
||||
|
||||
static ASSizeRange kSize = {{300, 0}, {300, 150}};
|
||||
@ -478,8 +482,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {3000, 3000};
|
||||
|
||||
ASRatioLayoutSpec *child2 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.0 child:subnodes[2]];
|
||||
child2.flexGrow = YES;
|
||||
child2.flexShrink = YES;
|
||||
ASLayoutOptions *layoutOptions2 = [ASLayoutSpec layoutOptionsForChild:child2];
|
||||
layoutOptions2.flexGrow = YES;
|
||||
layoutOptions2.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.
|
||||
@ -504,13 +509,13 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
|
||||
NSArray *subnodes = defaultSubnodes();
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).staticSize = {300, 50};
|
||||
((ASStaticSizeDisplayNode *)subnodes[0]).flexShrink = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].flexShrink = YES;
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 50};
|
||||
((ASStaticSizeDisplayNode *)subnodes[1]).flexShrink = NO;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].flexShrink = NO;
|
||||
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {200, 50};
|
||||
((ASStaticSizeDisplayNode *)subnodes[2]).flexShrink = YES;
|
||||
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].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.
|
||||
|
||||
@ -10,4 +10,4 @@ SPEC CHECKSUMS:
|
||||
FBSnapshotTestCase: 3dc3899168747a0319c5278f5b3445c13a6532dd
|
||||
OCMock: a6a7dc0e3997fb9f35d99f72528698ebf60d64f2
|
||||
|
||||
COCOAPODS: 0.37.2
|
||||
COCOAPODS: 0.35.0
|
||||
|
||||
@ -58,7 +58,9 @@
|
||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
05E2128219D4DB510098F589 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
|
||||
@ -135,7 +135,9 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
_imageNode.preferredFrameSize = _isImageEnlarged ? CGSizeMake(2.0 * kImageSize, 2.0 * kImageSize) : CGSizeMake(kImageSize, kImageSize);
|
||||
_textNode.flexShrink = YES;
|
||||
ASLayoutOptions *textNodeOptions = [[ASLayoutOptions alloc] init];
|
||||
textNodeOptions.flexShrink = YES;
|
||||
[ASLayoutSpec associateLayoutOptions:textNodeOptions withChild:_textNode];
|
||||
|
||||
ASStackLayoutSpec *stackSpec = [[ASStackLayoutSpec alloc] init];
|
||||
stackSpec.direction = ASStackLayoutDirectionHorizontal;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user