Summary: If there is a single child which is flex grow and flex shrink then instead of measuring and then shrinking we can just set the flex basis to zero as we know the final result will be that the child take up all remaining space. This is a re-land of D4147298. I have updated the diff to check explicitly for exact measure mode to also handle at_most case correctly. Reviewed By: gkassabli Differential Revision: D4153133 fbshipit-source-id: 2333150a83857cc30078cc8d52761cbd00652830
134 lines
4.3 KiB
C++
134 lines
4.3 KiB
C++
/**
|
|
* 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.
|
|
*/
|
|
|
|
#include <CSSLayout/CSSLayout.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
static CSSSize _measureMax(CSSNodeRef node,
|
|
float width,
|
|
CSSMeasureMode widthMode,
|
|
float height,
|
|
CSSMeasureMode heightMode) {
|
|
|
|
int *measureCount = (int *)CSSNodeGetContext(node);
|
|
(*measureCount)++;
|
|
|
|
return CSSSize {
|
|
.width = widthMode == CSSMeasureModeUndefined ? 10 : width,
|
|
.height = heightMode == CSSMeasureModeUndefined ? 10 : height,
|
|
};
|
|
}
|
|
|
|
static CSSSize _measureMin(CSSNodeRef node,
|
|
float width,
|
|
CSSMeasureMode widthMode,
|
|
float height,
|
|
CSSMeasureMode heightMode) {
|
|
|
|
int *measureCount = (int *)CSSNodeGetContext(node);
|
|
*measureCount = *measureCount + 1;
|
|
return CSSSize {
|
|
.width = widthMode == CSSMeasureModeUndefined || (widthMode == CSSMeasureModeAtMost && width > 10) ? 10 : width,
|
|
.height = heightMode == CSSMeasureModeUndefined || (heightMode == CSSMeasureModeAtMost && height > 10) ? 10 : height,
|
|
};
|
|
}
|
|
|
|
TEST(CSSLayoutTest, measure_once_single_flexible_child) {
|
|
const CSSNodeRef root = CSSNodeNew();
|
|
CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
|
|
CSSNodeStyleSetAlignItems(root, CSSAlignFlexStart);
|
|
CSSNodeStyleSetWidth(root, 100);
|
|
CSSNodeStyleSetHeight(root, 100);
|
|
|
|
const CSSNodeRef root_child0 = CSSNodeNew();
|
|
int measureCount = 0;
|
|
CSSNodeSetContext(root_child0, &measureCount);
|
|
CSSNodeSetMeasureFunc(root_child0, _measureMax);
|
|
CSSNodeStyleSetFlexGrow(root_child0, 1);
|
|
CSSNodeInsertChild(root, root_child0, 0);
|
|
|
|
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
|
|
|
|
ASSERT_EQ(1, measureCount);
|
|
|
|
CSSNodeFreeRecursive(root);
|
|
}
|
|
|
|
TEST(CSSLayoutTest, remeasure_with_same_exact_width_larger_than_needed_height) {
|
|
const CSSNodeRef root = CSSNodeNew();
|
|
|
|
const CSSNodeRef root_child0 = CSSNodeNew();
|
|
int measureCount = 0;
|
|
CSSNodeSetContext(root_child0, &measureCount);
|
|
CSSNodeSetMeasureFunc(root_child0, _measureMin);
|
|
CSSNodeInsertChild(root, root_child0, 0);
|
|
|
|
CSSNodeCalculateLayout(root, 100, 100, CSSDirectionLTR);
|
|
CSSNodeCalculateLayout(root, 100, 50, CSSDirectionLTR);
|
|
|
|
ASSERT_EQ(1, measureCount);
|
|
|
|
CSSNodeFreeRecursive(root);
|
|
}
|
|
|
|
TEST(CSSLayoutTest, remeasure_with_same_atmost_width_larger_than_needed_height) {
|
|
const CSSNodeRef root = CSSNodeNew();
|
|
CSSNodeStyleSetAlignItems(root, CSSAlignFlexStart);
|
|
|
|
const CSSNodeRef root_child0 = CSSNodeNew();
|
|
int measureCount = 0;
|
|
CSSNodeSetContext(root_child0, &measureCount);
|
|
CSSNodeSetMeasureFunc(root_child0, _measureMin);
|
|
CSSNodeInsertChild(root, root_child0, 0);
|
|
|
|
CSSNodeCalculateLayout(root, 100, 100, CSSDirectionLTR);
|
|
CSSNodeCalculateLayout(root, 100, 50, CSSDirectionLTR);
|
|
|
|
ASSERT_EQ(1, measureCount);
|
|
|
|
CSSNodeFreeRecursive(root);
|
|
}
|
|
|
|
TEST(CSSLayoutTest, remeasure_with_computed_width_larger_than_needed_height) {
|
|
const CSSNodeRef root = CSSNodeNew();
|
|
CSSNodeStyleSetAlignItems(root, CSSAlignFlexStart);
|
|
|
|
const CSSNodeRef root_child0 = CSSNodeNew();
|
|
int measureCount = 0;
|
|
CSSNodeSetContext(root_child0, &measureCount);
|
|
CSSNodeSetMeasureFunc(root_child0, _measureMin);
|
|
CSSNodeInsertChild(root, root_child0, 0);
|
|
|
|
CSSNodeCalculateLayout(root, 100, 100, CSSDirectionLTR);
|
|
CSSNodeStyleSetAlignItems(root, CSSAlignStretch);
|
|
CSSNodeCalculateLayout(root, 10, 50, CSSDirectionLTR);
|
|
|
|
ASSERT_EQ(1, measureCount);
|
|
|
|
CSSNodeFreeRecursive(root);
|
|
}
|
|
|
|
TEST(CSSLayoutTest, remeasure_with_atmost_computed_width_undefined_height) {
|
|
const CSSNodeRef root = CSSNodeNew();
|
|
CSSNodeStyleSetAlignItems(root, CSSAlignFlexStart);
|
|
|
|
const CSSNodeRef root_child0 = CSSNodeNew();
|
|
int measureCount = 0;
|
|
CSSNodeSetContext(root_child0, &measureCount);
|
|
CSSNodeSetMeasureFunc(root_child0, _measureMin);
|
|
CSSNodeInsertChild(root, root_child0, 0);
|
|
|
|
CSSNodeCalculateLayout(root, 100, CSSUndefined, CSSDirectionLTR);
|
|
CSSNodeCalculateLayout(root, 10, CSSUndefined, CSSDirectionLTR);
|
|
|
|
ASSERT_EQ(1, measureCount);
|
|
|
|
CSSNodeFreeRecursive(root);
|
|
}
|