Swiftgram/Source/Layout/ASDimension.mm
appleguy 55928f343d [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with improved behavior and cleaner integration (#343)
* [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with support for mixing with ASLayoutSpec.

After experimentation with the ASYogaLayoutSpec (or non-contiguous) approach to
integrating Yoga, test results and feedback from the authors of Yoga have shown
that this approach can't be made completely correct,

There are issues with some of the features required to represent Web-style
flexbox; in particular: padding, margins, and border handling have varience.

This diff is a first step towards a truly correct and elegant implementation of
Yoga integration with Texture. In addition to reducing the footprint of
the integration, which is an explicit goal of work at this stage, these changes
already support improved behavior - including mixing between ASLayoutSpecs
even as subnodes of Yoga layout-driven nodes, in addition to above them. Yoga
may be used for any set of nodes.

Because Yoga usage is limited at this time, it's safe to merge this diff and
further improvements will be refinements in this direction.

* [ASDKgram] Add Yoga layout implementation for PhotoCellNode.

* [Yoga] Final fixes for the upgraded implementation of the Contiguous layout mode.

* [Yoga] Add CHANGELOG.md entry and fix for Yoga rounding to screen scale.

* [Yoga] Minor cleanup to remove old comments and generalize utility methods.
2017-06-14 19:36:13 -07:00

129 lines
3.8 KiB
Plaintext

//
// ASDimension.mm
// Texture
//
// 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 /ASDK-Licenses directory of this source tree. An additional
// grant of patent rights can be found in the PATENTS file in the same directory.
//
// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present,
// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDimension.h>
#import <UIKit/UIGeometry.h>
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
#import <AsyncDisplayKit/ASAssert.h>
#pragma mark - ASDimension
ASDimension const ASDimensionAuto = {ASDimensionUnitAuto, 0};
ASOVERLOADABLE ASDimension ASDimensionMake(NSString *dimension)
{
if (dimension.length > 0) {
// Handle points
if ([dimension hasSuffix:@"pt"]) {
return ASDimensionMake(ASDimensionUnitPoints, ASCGFloatFromString(dimension));
}
// Handle auto
if ([dimension isEqualToString:@"auto"]) {
return ASDimensionAuto;
}
// Handle percent
if ([dimension hasSuffix:@"%"]) {
return ASDimensionMake(ASDimensionUnitFraction, (ASCGFloatFromString(dimension) / 100.0));
}
}
ASDisplayNodeCAssert(NO, @"Parsing dimension failed for: %@", dimension);
return ASDimensionAuto;
}
NSString *NSStringFromASDimension(ASDimension dimension)
{
switch (dimension.unit) {
case ASDimensionUnitPoints:
return [NSString stringWithFormat:@"%.0fpt", dimension.value];
case ASDimensionUnitFraction:
return [NSString stringWithFormat:@"%.0f%%", dimension.value * 100.0];
case ASDimensionUnitAuto:
return @"Auto";
}
}
#pragma mark - ASLayoutSize
ASLayoutSize const ASLayoutSizeAuto = {ASDimensionAuto, ASDimensionAuto};
#pragma mark - ASSizeRange
ASSizeRange const ASSizeRangeZero = {};
ASSizeRange const ASSizeRangeUnconstrained = { {0, 0}, { INFINITY, INFINITY }};
struct _Range {
CGFloat min;
CGFloat max;
/**
Intersects another dimension range. If the other range does not overlap, this size range "wins" by returning a
single point within its own range that is closest to the non-overlapping range.
*/
_Range intersect(const _Range &other) const
{
CGFloat newMin = MAX(min, other.min);
CGFloat newMax = MIN(max, other.max);
if (newMin <= newMax) {
return {newMin, newMax};
} else {
// No intersection. If we're before the other range, return our max; otherwise our min.
if (min < other.min) {
return {max, max};
} else {
return {min, min};
}
}
}
};
ASSizeRange ASSizeRangeIntersect(ASSizeRange sizeRange, ASSizeRange otherSizeRange)
{
auto w = _Range({sizeRange.min.width, sizeRange.max.width}).intersect({otherSizeRange.min.width, otherSizeRange.max.width});
auto h = _Range({sizeRange.min.height, sizeRange.max.height}).intersect({otherSizeRange.min.height, otherSizeRange.max.height});
return {{w.min, h.min}, {w.max, h.max}};
}
NSString *NSStringFromASSizeRange(ASSizeRange sizeRange)
{
return [NSString stringWithFormat:@"<ASSizeRange: min=%@, max=%@>",
NSStringFromCGSize(sizeRange.min),
NSStringFromCGSize(sizeRange.max)];
}
#if YOGA
#pragma mark - Yoga - ASEdgeInsets
ASEdgeInsets const ASEdgeInsetsZero = {};
extern ASEdgeInsets ASEdgeInsetsMake(UIEdgeInsets edgeInsets)
{
ASEdgeInsets asEdgeInsets = ASEdgeInsetsZero;
asEdgeInsets.top = ASDimensionMake(edgeInsets.top);
asEdgeInsets.left = ASDimensionMake(edgeInsets.left);
asEdgeInsets.bottom = ASDimensionMake(edgeInsets.bottom);
asEdgeInsets.right = ASDimensionMake(edgeInsets.right);
return asEdgeInsets;
}
#endif