mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
[ASLayout] Cache constrained size range
This commit is contained in:
@@ -1956,7 +1956,10 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
// Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct.
|
// Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct.
|
||||||
if (layout.layoutableObject != self) {
|
if (layout.layoutableObject != self) {
|
||||||
layout.position = CGPointZero;
|
layout.position = CGPointZero;
|
||||||
layout = [ASLayout layoutWithLayoutableObject:self size:layout.size sublayouts:@[layout]];
|
layout = [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:layout.size
|
||||||
|
sublayouts:@[layout]];
|
||||||
}
|
}
|
||||||
return [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
return [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
||||||
if (self.usesImplicitHierarchyManagement) {
|
if (self.usesImplicitHierarchyManagement) {
|
||||||
@@ -1969,7 +1972,9 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
// If neither -layoutSpecThatFits: nor -calculateSizeThatFits: is overridden by subclassses, preferredFrameSize should be used,
|
// If neither -layoutSpecThatFits: nor -calculateSizeThatFits: is overridden by subclassses, preferredFrameSize should be used,
|
||||||
// assume that the default implementation of -calculateSizeThatFits: returns it.
|
// assume that the default implementation of -calculateSizeThatFits: returns it.
|
||||||
CGSize size = [self calculateSizeThatFits:constrainedSize.max];
|
CGSize size = [self calculateSizeThatFits:constrainedSize.max];
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:ASSizeRangeClamp(constrainedSize, size)];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:ASSizeRangeClamp(constrainedSize, size)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,10 @@ static NSString * const kBackgroundChildKey = @"kBackgroundChildKey";
|
|||||||
contentsLayout.position = CGPointZero;
|
contentsLayout.position = CGPointZero;
|
||||||
[sublayouts addObject:contentsLayout];
|
[sublayouts addObject:contentsLayout];
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:contentsLayout.size sublayouts:sublayouts];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:contentsLayout.size
|
||||||
|
sublayouts:sublayouts];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBackground:(id<ASLayoutable>)background
|
- (void)setBackground:(id<ASLayoutable>)background
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
|
|||||||
|
|
||||||
if (self.child == nil) {
|
if (self.child == nil) {
|
||||||
ASDisplayNodeAssert(NO, @"Inset spec measured without a child. The spec will do nothing.");
|
ASDisplayNodeAssert(NO, @"Inset spec measured without a child. The spec will do nothing.");
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:CGSizeZero];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:CGSizeZero];
|
||||||
}
|
}
|
||||||
|
|
||||||
ASLayout *sublayout = [self.child measureWithSizeRange:insetConstrainedSize];
|
ASLayout *sublayout = [self.child measureWithSizeRange:insetConstrainedSize];
|
||||||
@@ -112,7 +114,10 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
|
|||||||
|
|
||||||
sublayout.position = CGPointMake(x, y);
|
sublayout.position = CGPointMake(x, y);
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:computedSize sublayouts:@[sublayout]];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:computedSize
|
||||||
|
sublayouts:@[sublayout]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ extern BOOL CGPointIsNull(CGPoint point);
|
|||||||
*/
|
*/
|
||||||
@property (nonatomic, readwrite) CGPoint position;
|
@property (nonatomic, readwrite) CGPoint position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size range that was use to determine the size of the layout.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, readonly) ASSizeRange constrainedSizeRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of ASLayouts. Each must have a valid non-null position.
|
* Array of ASLayouts. Each must have a valid non-null position.
|
||||||
*/
|
*/
|
||||||
@@ -67,6 +72,7 @@ extern BOOL CGPointIsNull(CGPoint point);
|
|||||||
* @param sublayouts Sublayouts belong to the new layout.
|
* @param sublayouts Sublayouts belong to the new layout.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
position:(CGPoint)position
|
position:(CGPoint)position
|
||||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts
|
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts
|
||||||
@@ -85,6 +91,7 @@ extern BOOL CGPointIsNull(CGPoint point);
|
|||||||
* @param sublayouts Sublayouts belong to the new layout.
|
* @param sublayouts Sublayouts belong to the new layout.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
||||||
|
|
||||||
@@ -97,7 +104,9 @@ extern BOOL CGPointIsNull(CGPoint point);
|
|||||||
*
|
*
|
||||||
* @param size The size of this layout.
|
* @param size The size of this layout.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size;
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
|
size:(CGSize)size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience initializer that is flattened and has CGPointNull position.
|
* Convenience initializer that is flattened and has CGPointNull position.
|
||||||
@@ -109,6 +118,7 @@ extern BOOL CGPointIsNull(CGPoint point);
|
|||||||
* @param sublayouts Sublayouts belong to the new layout.
|
* @param sublayouts Sublayouts belong to the new layout.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)flattenedLayoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)flattenedLayoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ extern BOOL CGPointIsNull(CGPoint point)
|
|||||||
@implementation ASLayout
|
@implementation ASLayout
|
||||||
|
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
position:(CGPoint)position
|
position:(CGPoint)position
|
||||||
sublayouts:(NSArray *)sublayouts
|
sublayouts:(NSArray *)sublayouts
|
||||||
@@ -46,6 +47,7 @@ extern BOOL CGPointIsNull(CGPoint point)
|
|||||||
} else {
|
} else {
|
||||||
size = CGSizeMake(ASCeilPixelValue(size.width), ASCeilPixelValue(size.height));
|
size = CGSizeMake(ASCeilPixelValue(size.width), ASCeilPixelValue(size.height));
|
||||||
}
|
}
|
||||||
|
l->_constrainedSizeRange = sizeRange;
|
||||||
l->_size = size;
|
l->_size = size;
|
||||||
|
|
||||||
if (CGPointIsNull(position) == NO) {
|
if (CGPointIsNull(position) == NO) {
|
||||||
@@ -68,22 +70,39 @@ extern BOOL CGPointIsNull(CGPoint point)
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
sublayouts:(NSArray *)sublayouts
|
sublayouts:(NSArray *)sublayouts
|
||||||
{
|
{
|
||||||
return [self layoutWithLayoutableObject:layoutableObject size:size position:CGPointNull sublayouts:sublayouts flattened:NO];
|
return [self layoutWithLayoutableObject:layoutableObject
|
||||||
|
constrainedSizeRange:sizeRange
|
||||||
|
size:size
|
||||||
|
position:CGPointNull
|
||||||
|
sublayouts:sublayouts
|
||||||
|
flattened:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size
|
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
|
size:(CGSize)size
|
||||||
{
|
{
|
||||||
return [self layoutWithLayoutableObject:layoutableObject size:size sublayouts:nil];
|
return [self layoutWithLayoutableObject:layoutableObject
|
||||||
|
constrainedSizeRange:sizeRange
|
||||||
|
size:size
|
||||||
|
sublayouts:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)flattenedLayoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)flattenedLayoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts
|
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts
|
||||||
{
|
{
|
||||||
return [self layoutWithLayoutableObject:layoutableObject size:size position:CGPointNull sublayouts:sublayouts flattened:YES];
|
return [self layoutWithLayoutableObject:layoutableObject
|
||||||
|
constrainedSizeRange:sizeRange
|
||||||
|
size:size
|
||||||
|
position:CGPointNull
|
||||||
|
sublayouts:sublayouts
|
||||||
|
flattened:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASLayout *)flattenedLayoutUsingPredicateBlock:(BOOL (^)(ASLayout *))predicateBlock
|
- (ASLayout *)flattenedLayoutUsingPredicateBlock:(BOOL (^)(ASLayout *))predicateBlock
|
||||||
@@ -110,6 +129,7 @@ extern BOOL CGPointIsNull(CGPoint point)
|
|||||||
|
|
||||||
if (predicateBlock(context.layout)) {
|
if (predicateBlock(context.layout)) {
|
||||||
[flattenedSublayouts addObject:[ASLayout layoutWithLayoutableObject:context.layout.layoutableObject
|
[flattenedSublayouts addObject:[ASLayout layoutWithLayoutableObject:context.layout.layoutableObject
|
||||||
|
constrainedSizeRange:context.layout.constrainedSizeRange
|
||||||
size:context.layout.size
|
size:context.layout.size
|
||||||
position:context.absolutePosition
|
position:context.absolutePosition
|
||||||
sublayouts:nil
|
sublayouts:nil
|
||||||
@@ -124,7 +144,10 @@ extern BOOL CGPointIsNull(CGPoint point)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout flattenedLayoutWithLayoutableObject:_layoutableObject size:_size sublayouts:flattenedSublayouts];
|
return [ASLayout flattenedLayoutWithLayoutableObject:_layoutableObject
|
||||||
|
constrainedSizeRange:_constrainedSizeRange
|
||||||
|
size:_size
|
||||||
|
sublayouts:flattenedSublayouts];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)frame
|
- (CGRect)frame
|
||||||
|
|||||||
@@ -52,7 +52,9 @@
|
|||||||
|
|
||||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||||
{
|
{
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:constrainedSize.min];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:constrainedSize.min];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id<ASLayoutable>)finalLayoutable
|
- (id<ASLayoutable>)finalLayoutable
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ static NSString * const kOverlayChildKey = @"kOverlayChildKey";
|
|||||||
[sublayouts addObject:overlayLayout];
|
[sublayouts addObject:overlayLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:contentsLayout.size sublayouts:sublayouts];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:contentsLayout.size
|
||||||
|
sublayouts:sublayouts];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -72,7 +72,10 @@
|
|||||||
const ASSizeRange childRange = (bestSize == sizeOptions.end()) ? constrainedSize : ASSizeRangeMake(*bestSize, *bestSize);
|
const ASSizeRange childRange = (bestSize == sizeOptions.end()) ? constrainedSize : ASSizeRangeMake(*bestSize, *bestSize);
|
||||||
ASLayout *sublayout = [self.child measureWithSizeRange:childRange];
|
ASLayout *sublayout = [self.child measureWithSizeRange:childRange];
|
||||||
sublayout.position = CGPointZero;
|
sublayout.position = CGPointZero;
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:sublayout.size sublayouts:@[sublayout]];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:sublayout.size
|
||||||
|
sublayouts:@[sublayout]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -89,7 +89,10 @@
|
|||||||
ASRoundPixelValue((size.height - sublayout.size.height) * yPosition)
|
ASRoundPixelValue((size.height - sublayout.size.height) * yPosition)
|
||||||
};
|
};
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:size sublayouts:@[sublayout]];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:size
|
||||||
|
sublayouts:@[sublayout]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGFloat)proportionOfAxisForAxisPosition:(ASRelativeLayoutSpecPosition)position
|
- (CGFloat)proportionOfAxisForAxisPosition:(ASRelativeLayoutSpecPosition)position
|
||||||
|
|||||||
@@ -124,7 +124,9 @@
|
|||||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||||
{
|
{
|
||||||
if (self.children.count == 0) {
|
if (self.children.count == 0) {
|
||||||
return [ASLayout layoutWithLayoutableObject:self size:constrainedSize.min];
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
|
size:constrainedSize.min];
|
||||||
}
|
}
|
||||||
|
|
||||||
ASStackLayoutSpecStyle style = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems, .baselineRelativeArrangement = _baselineRelativeArrangement};
|
ASStackLayoutSpecStyle style = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems, .baselineRelativeArrangement = _baselineRelativeArrangement};
|
||||||
@@ -163,6 +165,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
size:ASSizeRangeClamp(constrainedSize, finalSize)
|
size:ASSizeRangeClamp(constrainedSize, finalSize)
|
||||||
sublayouts:sublayouts];
|
sublayouts:sublayouts];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:constrainedSize
|
||||||
size:ASSizeRangeClamp(constrainedSize, size)
|
size:ASSizeRangeClamp(constrainedSize, size)
|
||||||
sublayouts:sublayouts];
|
sublayouts:sublayouts];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
|
|||||||
const CGFloat exactStackDimension = ASRelativeDimensionResolve(flexBasis, stackDimension(style.direction, size));
|
const CGFloat exactStackDimension = ASRelativeDimensionResolve(flexBasis, stackDimension(style.direction, size));
|
||||||
|
|
||||||
if (useOptimizedFlexing && isFlexibleInBothDirections(child)) {
|
if (useOptimizedFlexing && isFlexibleInBothDirections(child)) {
|
||||||
return { child, [ASLayout layoutWithLayoutableObject:child size:{0, 0}] };
|
return { child, [ASLayout layoutWithLayoutableObject:child constrainedSizeRange:sizeRange size:{0, 0}] };
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
child,
|
child,
|
||||||
|
|||||||
@@ -55,7 +55,10 @@
|
|||||||
{
|
{
|
||||||
ASLayout *layout = [layoutSpecUnderTest measureWithSizeRange:sizeRange];
|
ASLayout *layout = [layoutSpecUnderTest measureWithSizeRange:sizeRange];
|
||||||
layout.position = CGPointZero;
|
layout.position = CGPointZero;
|
||||||
layout = [ASLayout layoutWithLayoutableObject:self size:layout.size sublayouts:@[layout]];
|
layout = [ASLayout layoutWithLayoutableObject:self
|
||||||
|
constrainedSizeRange:sizeRange
|
||||||
|
size:layout.size
|
||||||
|
sublayouts:@[layout]];
|
||||||
_layoutUnderTest = [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
_layoutUnderTest = [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
||||||
return [self.subnodes containsObject:(ASDisplayNode *)evaluatedLayout.layoutableObject];
|
return [self.subnodes containsObject:(ASDisplayNode *)evaluatedLayout.layoutableObject];
|
||||||
}];
|
}];
|
||||||
|
|||||||
Reference in New Issue
Block a user