ComponentKit/LayoutComponents/CKStaticLayoutComponent.mm (67 lines of code) (raw):
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "CKStaticLayoutComponent.h"
#include <algorithm>
#import <ComponentKit/CKComponentInternal.h>
#import <ComponentKit/CKMacros.h>
#import <ComponentKit/CKFunctionalHelpers.h>
#import <ComponentKit/CKSizeAssert.h>
#import "CKComponentSubclass.h"
@implementation CKStaticLayoutComponent
{
std::vector<CKStaticLayoutComponentChild> _children;
}
+ (instancetype)newWithView:(const CKComponentViewConfiguration &)view
size:(const RCComponentSize &)size
children:(RCContainerWrapper<std::vector<CKStaticLayoutComponentChild>> &&)children
{
CKStaticLayoutComponent *c = [super newWithView:view size:size];
if (c) {
c->_children = children.take();
}
return c;
}
+ (instancetype)newWithChildren:(RCContainerWrapper<std::vector<CKStaticLayoutComponentChild>> &&)children
{
return [self newWithView:{} size:{} children:std::move(children)];
}
- (unsigned int)numberOfChildren
{
return (unsigned int)_children.size();
}
- (id<CKMountable>)childAtIndex:(unsigned int)index
{
if (index < _children.size()) {
return _children[index].component;
}
RCFailAssertWithCategory(self.className, @"Index %u is out of bounds %u", index, [self numberOfChildren]);
return nil;
}
- (RCLayout)computeLayoutThatFits:(CKSizeRange)constrainedSize
{
CGSize size = {
isinf(constrainedSize.max.width) ? kCKComponentParentDimensionUndefined : constrainedSize.max.width,
isinf(constrainedSize.max.height) ? kCKComponentParentDimensionUndefined : constrainedSize.max.height
};
auto layoutChildren = CK::map(_children, [&constrainedSize, &size](CKStaticLayoutComponentChild child) {
CGSize autoMaxSize = {
std::max(constrainedSize.max.width - child.position.x, (CGFloat)0),
std::max(constrainedSize.max.height - child.position.y, (CGFloat)0)
};
CKSizeRange childConstraint = child.size.resolveSizeRange(size, {{0,0}, autoMaxSize});
CKAssertSizeRange(childConstraint);
return RCLayoutChild({child.position, CKComputeComponentLayout(child.component, childConstraint, size)});
});
if (isnan(size.width)) {
size.width = constrainedSize.min.width;
for (auto &child : layoutChildren) {
size.width = MAX(size.width, child.position.x + child.layout.size.width);
}
}
if (isnan(size.height)) {
size.height = constrainedSize.min.height;
for (auto &child : layoutChildren) {
size.height = MAX(size.height, child.position.y + child.layout.size.height);
}
}
return {self, constrainedSize.clamp(size), layoutChildren};
}
@end