Include transform property when calling getRelativeLayoutMetrics

Summary:
Changelog: [Internal]

Current implementation of `measure` doesn't take transform into account..

So if you had a view which has width and height 100 and had `Scale(0.5, 0.5, 1)` (this will shrink view by half). Calling `getRelativeLayoutMetrics` would report its size being `{100, 100}`.
This applies if view's parent has transformation as well, because transformation is applied to all subviews of the view as well.

Reviewed By: mdvacca

Differential Revision: D20621590

fbshipit-source-id: 2cf902a0494291c821ecada56f810c5e6620db5a
This commit is contained in:
Samuel Susla 2020-03-30 04:00:43 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 26b209431b
Коммит bbd91446dd
2 изменённых файлов: 75 добавлений и 8 удалений

Просмотреть файл

@ -55,15 +55,15 @@ static LayoutMetrics calculateOffsetForLayoutMetrics(
return EmptyLayoutMetrics;
}
auto origin = layoutableCurrentShadowNode->getLayoutMetrics().frame.origin;
auto frame = layoutableCurrentShadowNode->getLayoutMetrics().frame;
if (policy.includeTransform) {
// The check for ScrollView will be implemented after we have
// a dedicated trait (part of `ShadowNodeTraits`) for that.
origin = origin * layoutableCurrentShadowNode->getTransform();
layoutMetrics.frame.size = layoutMetrics.frame.size *
layoutableCurrentShadowNode->getTransform();
frame = frame * layoutableCurrentShadowNode->getTransform();
}
layoutMetrics.frame.origin += origin;
layoutMetrics.frame.origin += frame.origin;
}
return layoutMetrics;
}
@ -132,9 +132,13 @@ LayoutMetrics LayoutableShadowNode::getRelativeLayoutMetrics(
return EmptyLayoutMetrics;
}
auto layoutMetrics = dynamic_cast<LayoutableShadowNode const *>(newestChild)
->getLayoutMetrics();
auto layoutableNewestChild =
dynamic_cast<LayoutableShadowNode const *>(newestChild);
auto layoutMetrics = layoutableNewestChild->getLayoutMetrics();
if (policy.includeTransform) {
layoutMetrics.frame =
layoutMetrics.frame * layoutableNewestChild->getTransform();
}
return calculateOffsetForLayoutMetrics(layoutMetrics, ancestors, policy);
}

Просмотреть файл

@ -71,14 +71,33 @@ class LayoutableShadowNodeTest : public ::testing::Test {
familyAAA,
traits);
auto familyAAAA = std::make_shared<ShadowNodeFamily>(
ShadowNodeFamilyFragment{
/* .tag = */ 11,
/* .surfaceId = */ 1,
/* .eventEmitter = */ nullptr,
},
eventDispatcher_,
componentDescriptor_);
nodeAAAA_ = std::make_shared<TestShadowNode>(
ShadowNodeFragment{
/* .props = */ std::make_shared<const TestProps>(),
/* .children = */ ShadowNode::emptySharedShadowNodeSharedList(),
},
familyAAAA,
traits);
nodeA_->appendChild(nodeAA_);
nodeAA_->appendChild(nodeAAA_);
nodeAAA_->appendChild(nodeAAAA_);
}
std::shared_ptr<EventDispatcher const> eventDispatcher_;
std::shared_ptr<TestShadowNode> nodeA_;
std::shared_ptr<TestShadowNode> nodeAA_;
std::shared_ptr<TestShadowNode> nodeAAA_;
std::shared_ptr<TestShadowNode> nodeAAAA_;
TestComponentDescriptor componentDescriptor_;
};
@ -98,6 +117,50 @@ TEST_F(LayoutableShadowNodeTest, relativeLayoutMetrics) {
EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 20);
}
TEST_F(LayoutableShadowNodeTest, relativeLayoutMetricsOnTransformedNode) {
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.size = {1000, 1000};
nodeA_->setLayoutMetrics(layoutMetrics);
layoutMetrics.frame.origin = {10, 20};
layoutMetrics.frame.size = {100, 200};
nodeAA_->_transform = Transform::Scale(0.5, 0.5, 1);
nodeAA_->setLayoutMetrics(layoutMetrics);
auto relativeLayoutMetrics = nodeAA_->getRelativeLayoutMetrics(*nodeA_, {});
EXPECT_EQ(relativeLayoutMetrics.frame.origin.x, 35);
EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 70);
EXPECT_EQ(relativeLayoutMetrics.frame.size.width, 50);
EXPECT_EQ(relativeLayoutMetrics.frame.size.height, 100);
}
TEST_F(LayoutableShadowNodeTest, relativeLayoutMetricsOnTransformedParent) {
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.size = {1000, 1000};
nodeA_->setLayoutMetrics(layoutMetrics);
nodeAA_->setLayoutMetrics(layoutMetrics);
layoutMetrics.frame.origin = {10, 10};
layoutMetrics.frame.size = {100, 100};
nodeAAA_->_transform = Transform::Scale(0.5, 0.5, 1);
nodeAAA_->setLayoutMetrics(layoutMetrics);
layoutMetrics.frame.origin = {10, 10};
layoutMetrics.frame.size = {50, 50};
nodeAAAA_->setLayoutMetrics(layoutMetrics);
auto relativeLayoutMetrics =
nodeAAAA_->getRelativeLayoutMetrics(*nodeAA_, {});
EXPECT_EQ(relativeLayoutMetrics.frame.origin.x, 45);
EXPECT_EQ(relativeLayoutMetrics.frame.origin.y, 45);
EXPECT_EQ(relativeLayoutMetrics.frame.size.width, 25);
EXPECT_EQ(relativeLayoutMetrics.frame.size.height, 25);
}
TEST_F(LayoutableShadowNodeTest, relativeLayoutMetricsOnSameNode) {
auto layoutMetrics = EmptyLayoutMetrics;
layoutMetrics.frame.origin = {10, 20};