mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Remove ASLayoutChild. ASLayout now has a position property defaults to (NAN, NAN).
This commit is contained in:
@@ -1426,8 +1426,8 @@ static NSInteger incrementIfFound(NSInteger i) {
|
|||||||
subnodeSize.width, subnodeSize.height);
|
subnodeSize.width, subnodeSize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ASLayoutChild *child in context.layout.children) {
|
for (ASLayout *child in context.layout.children) {
|
||||||
stack.push({child.layout, context.absolutePosition + child.position, NO});
|
stack.push({child, context.absolutePosition + child.position, NO});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,14 +44,16 @@
|
|||||||
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
||||||
{
|
{
|
||||||
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
|
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
|
||||||
|
contentsLayout.position = CGPointZero;
|
||||||
|
|
||||||
NSMutableArray *children = [NSMutableArray arrayWithCapacity:2];
|
NSMutableArray *children = [NSMutableArray arrayWithCapacity:2];
|
||||||
if (_background) {
|
if (_background) {
|
||||||
// Size background to exactly the same size.
|
// Size background to exactly the same size.
|
||||||
ASLayout *backgroundLayout = [_background calculateLayoutThatFits:{contentsLayout.size, contentsLayout.size}];
|
ASLayout *backgroundLayout = [_background calculateLayoutThatFits:{contentsLayout.size, contentsLayout.size}];
|
||||||
[children addObject:[ASLayoutChild newWithPosition:{0,0} layout:backgroundLayout]];
|
backgroundLayout.position = CGPointZero;
|
||||||
|
[children addObject:backgroundLayout];
|
||||||
}
|
}
|
||||||
[children addObject:[ASLayoutChild newWithPosition:{0,0} layout:contentsLayout]];
|
[children addObject:contentsLayout];
|
||||||
|
|
||||||
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:children];
|
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:children];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,14 +67,12 @@
|
|||||||
// Compute the centered postion for the child
|
// Compute the centered postion for the child
|
||||||
BOOL shouldCenterAlongX = (_centeringOptions & ASCenterLayoutNodeCenteringX);
|
BOOL shouldCenterAlongX = (_centeringOptions & ASCenterLayoutNodeCenteringX);
|
||||||
BOOL shouldCenterAlongY = (_centeringOptions & ASCenterLayoutNodeCenteringY);
|
BOOL shouldCenterAlongY = (_centeringOptions & ASCenterLayoutNodeCenteringY);
|
||||||
const CGPoint childPosition = {
|
childLayout.position = {
|
||||||
ASRoundPixelValue(shouldCenterAlongX ? (size.width - childLayout.size.width) * 0.5f : 0),
|
ASRoundPixelValue(shouldCenterAlongX ? (size.width - childLayout.size.width) * 0.5f : 0),
|
||||||
ASRoundPixelValue(shouldCenterAlongY ? (size.height - childLayout.size.height) * 0.5f : 0)
|
ASRoundPixelValue(shouldCenterAlongY ? (size.height - childLayout.size.height) * 0.5f : 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
return [ASLayout newWithLayoutableObject:self
|
return [ASLayout newWithLayoutableObject:self size:size children:@[childLayout]];
|
||||||
size:size
|
|
||||||
children:@[[ASLayoutChild newWithPosition:childPosition layout:childLayout]]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -99,9 +99,10 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
|
|||||||
constrainedSize.max.height -
|
constrainedSize.max.height -
|
||||||
(finite(_insets.bottom,
|
(finite(_insets.bottom,
|
||||||
centerInset(constrainedSize.max.height, childLayout.size.height)) + childLayout.size.height));
|
centerInset(constrainedSize.max.height, childLayout.size.height)) + childLayout.size.height));
|
||||||
return [ASLayout newWithLayoutableObject:self
|
|
||||||
size:computedSize
|
childLayout.position = CGPointMake(x, y);
|
||||||
children:@[[ASLayoutChild newWithPosition:{x,y} layout:childLayout]]];
|
|
||||||
|
return [ASLayout newWithLayoutableObject:self size:computedSize children:@[childLayout]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,35 +12,45 @@
|
|||||||
#import <AsyncDisplayKit/ASAssert.h>
|
#import <AsyncDisplayKit/ASAssert.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||||
|
|
||||||
/** Represents the computed size of a layout node, as well as the computed sizes and positions of its children. */
|
extern CGPoint const CGPointNull;
|
||||||
|
|
||||||
|
extern BOOL CGPointIsNull(CGPoint point);
|
||||||
|
|
||||||
|
/** Represents a computed immutable layout tree. */
|
||||||
@interface ASLayout : NSObject
|
@interface ASLayout : NSObject
|
||||||
|
|
||||||
@property (nonatomic, readonly) id<ASLayoutable> layoutableObject;
|
@property (nonatomic, readonly) id<ASLayoutable> layoutableObject;
|
||||||
@property (nonatomic, readonly) CGSize size;
|
@property (nonatomic, readonly) CGSize size;
|
||||||
/**
|
/**
|
||||||
* Each item is of type ASLayoutChild.
|
* Position parent (if any). Default to CGPointNull.
|
||||||
|
*
|
||||||
|
* @discussion Before being used as a child layout, this property must be set and no longer equal CGPointNull.
|
||||||
|
*
|
||||||
|
* @discussion Unlike all other properties, this property is read-write because often by initializaion time, it has yet been determined.
|
||||||
|
* To enforce immutability, this property can be set once and only once.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@property (nonatomic, readwrite) CGPoint position;
|
||||||
|
/**
|
||||||
|
* Array of ASLayout children. Each child must have a valid non-null position.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, readonly) NSArray *children;
|
@property (nonatomic, readonly) NSArray *children;
|
||||||
|
|
||||||
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
|
position:(CGPoint)position
|
||||||
children:(NSArray *)children;
|
children:(NSArray *)children;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience that does not have any children.
|
* Convenience that has CGPointNull position.
|
||||||
|
*/
|
||||||
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
size:(CGSize)size
|
||||||
|
children:(NSArray *)children;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience that has CGPointNull position and no children.
|
||||||
*/
|
*/
|
||||||
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size;
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASLayoutChild : NSObject
|
|
||||||
|
|
||||||
@property (nonatomic, readonly) CGPoint position;
|
|
||||||
@property (nonatomic, readonly) ASLayout *layout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Designated initializer
|
|
||||||
*/
|
|
||||||
+ (instancetype)newWithPosition:(CGPoint)position layout:(ASLayout *)layout;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|||||||
@@ -9,39 +9,53 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ASLayout.h"
|
#import "ASLayout.h"
|
||||||
|
#import "ASAssert.h"
|
||||||
|
|
||||||
|
CGPoint const CGPointNull = {NAN, NAN};
|
||||||
|
|
||||||
|
extern BOOL CGPointIsNull(CGPoint point)
|
||||||
|
{
|
||||||
|
return isnan(point.x) && isnan(point.y);
|
||||||
|
}
|
||||||
|
|
||||||
@implementation ASLayout
|
@implementation ASLayout
|
||||||
|
|
||||||
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
size:(CGSize)size
|
size:(CGSize)size
|
||||||
|
position:(CGPoint)position
|
||||||
children:(NSArray *)children
|
children:(NSArray *)children
|
||||||
{
|
{
|
||||||
|
for (ASLayout *child in children) {
|
||||||
|
ASDisplayNodeAssert(!CGPointIsNull(child.position), @"Invalid position is not allowed in children.");
|
||||||
|
}
|
||||||
|
|
||||||
ASLayout *l = [super new];
|
ASLayout *l = [super new];
|
||||||
if (l) {
|
if (l) {
|
||||||
l->_layoutableObject = layoutableObject;
|
l->_layoutableObject = layoutableObject;
|
||||||
l->_size = size;
|
l->_size = size;
|
||||||
|
l->_position = position;
|
||||||
l->_children = [children copy];
|
l->_children = [children copy];
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||||
|
size:(CGSize)size
|
||||||
|
children:(NSArray *)children
|
||||||
|
{
|
||||||
|
return [self newWithLayoutableObject:layoutableObject size:size position:CGPointNull children:children];
|
||||||
|
}
|
||||||
|
|
||||||
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size
|
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size
|
||||||
{
|
{
|
||||||
return [self newWithLayoutableObject:layoutableObject size:size children:nil];
|
return [self newWithLayoutableObject:layoutableObject size:size children:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
- (void)setPosition:(CGPoint)position
|
||||||
|
|
||||||
@implementation ASLayoutChild
|
|
||||||
|
|
||||||
+ (instancetype)newWithPosition:(CGPoint)position layout:(ASLayout *)layout
|
|
||||||
{
|
{
|
||||||
ASLayoutChild *c = [super new];
|
ASDisplayNodeAssert(CGPointIsNull(_position), @"Position can be set once and only once.");
|
||||||
if (c) {
|
ASDisplayNodeAssert(!CGPointIsNull(position), @"Position must not be set to null.");
|
||||||
c->_position = position;
|
_position = position;
|
||||||
c->_layout = layout;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -41,10 +41,12 @@
|
|||||||
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
||||||
{
|
{
|
||||||
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
|
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
|
||||||
NSMutableArray *layoutChildren = [NSMutableArray arrayWithObject:[ASLayoutChild newWithPosition:{0, 0} layout:contentsLayout]];
|
contentsLayout.position = CGPointZero;
|
||||||
|
NSMutableArray *layoutChildren = [NSMutableArray arrayWithObject:contentsLayout];
|
||||||
if (_overlay) {
|
if (_overlay) {
|
||||||
ASLayout *overlayLayout = [_overlay calculateLayoutThatFits:{contentsLayout.size, contentsLayout.size}];
|
ASLayout *overlayLayout = [_overlay calculateLayoutThatFits:{contentsLayout.size, contentsLayout.size}];
|
||||||
[layoutChildren addObject:[ASLayoutChild newWithPosition:{0, 0} layout:overlayLayout]];
|
overlayLayout.position = CGPointZero;
|
||||||
|
[layoutChildren addObject:overlayLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:layoutChildren];
|
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:layoutChildren];
|
||||||
|
|||||||
@@ -68,9 +68,8 @@
|
|||||||
// If there is no max size in *either* dimension, we can't apply the ratio, so just pass our size range through.
|
// If there is no max size in *either* dimension, we can't apply the ratio, so just pass our size range through.
|
||||||
const ASSizeRange childRange = (bestSize == sizeOptions.end()) ? constrainedSize : ASSizeRangeMake(*bestSize, *bestSize);
|
const ASSizeRange childRange = (bestSize == sizeOptions.end()) ? constrainedSize : ASSizeRangeMake(*bestSize, *bestSize);
|
||||||
ASLayout *childLayout = [_child calculateLayoutThatFits:childRange];
|
ASLayout *childLayout = [_child calculateLayoutThatFits:childRange];
|
||||||
return [ASLayout newWithLayoutableObject:self
|
childLayout.position = CGPointZero;
|
||||||
size:childLayout.size
|
return [ASLayout newWithLayoutableObject:self size:childLayout.size children:@[childLayout]];
|
||||||
children:@[[ASLayoutChild newWithPosition:{0, 0} layout:childLayout]]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -68,22 +68,22 @@
|
|||||||
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, child.size)
|
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, child.size)
|
||||||
? ASSizeRangeMake({0, 0}, autoMaxSize)
|
? ASSizeRangeMake({0, 0}, autoMaxSize)
|
||||||
: ASRelativeSizeRangeResolve(child.size, size);
|
: ASRelativeSizeRangeResolve(child.size, size);
|
||||||
ASLayoutChild *layoutChild = [ASLayoutChild newWithPosition:child.position
|
ASLayout *childLayout = [child.node calculateLayoutThatFits:childConstraint];
|
||||||
layout:[child.node calculateLayoutThatFits:childConstraint]];
|
childLayout.position = child.position;
|
||||||
[layoutChildren addObject:layoutChild];
|
[layoutChildren addObject:childLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isnan(size.width)) {
|
if (isnan(size.width)) {
|
||||||
size.width = constrainedSize.min.width;
|
size.width = constrainedSize.min.width;
|
||||||
for (ASLayoutChild *child in layoutChildren) {
|
for (ASLayout *child in layoutChildren) {
|
||||||
size.width = MAX(size.width, child.position.x + child.layout.size.width);
|
size.width = MAX(size.width, child.position.x + child.size.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isnan(size.height)) {
|
if (isnan(size.height)) {
|
||||||
size.height = constrainedSize.min.height;
|
size.height = constrainedSize.min.height;
|
||||||
for (ASLayoutChild *child in layoutChildren) {
|
for (ASLayout *child in layoutChildren) {
|
||||||
size.height = MAX(size.height, child.position.y + child.layout.size.height);
|
size.height = MAX(size.height, child.position.y + child.size.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
/** Represents a set of laid out and positioned stack layout children. */
|
/** Represents a set of laid out and positioned stack layout children. */
|
||||||
struct ASStackPositionedLayout {
|
struct ASStackPositionedLayout {
|
||||||
const std::vector<ASLayoutChild *> children;
|
const std::vector<ASLayout *> children;
|
||||||
const CGFloat crossSize;
|
const CGFloat crossSize;
|
||||||
|
|
||||||
/** Given an unpositioned layout, computes the positions each child should be placed at. */
|
/** Given an unpositioned layout, computes the positions each child should be placed at. */
|
||||||
|
|||||||
@@ -47,16 +47,15 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutNodeStyle &style
|
|||||||
|
|
||||||
CGPoint p = directionPoint(style.direction, offset, 0);
|
CGPoint p = directionPoint(style.direction, offset, 0);
|
||||||
BOOL first = YES;
|
BOOL first = YES;
|
||||||
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayoutChild *{
|
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayout *{
|
||||||
p = p + directionPoint(style.direction, l.child.spacingBefore, 0);
|
p = p + directionPoint(style.direction, l.child.spacingBefore, 0);
|
||||||
if (!first) {
|
if (!first) {
|
||||||
p = p + directionPoint(style.direction, style.spacing, 0);
|
p = p + directionPoint(style.direction, style.spacing, 0);
|
||||||
}
|
}
|
||||||
first = NO;
|
first = NO;
|
||||||
ASLayoutChild *c = [ASLayoutChild newWithPosition:p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize))
|
l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize));
|
||||||
layout:l.layout];
|
|
||||||
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.spacingAfter, 0);
|
||||||
return c;
|
return l.layout;
|
||||||
});
|
});
|
||||||
return {stackedChildren, crossSize};
|
return {stackedChildren, crossSize};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user