Files
react-native/ReactCommon/fabric/components/slider/SliderShadowNode.cpp
T
Oleksandr MelnykovandFacebook Github Bot 299c984964 Pass surface ID to measure function in Java to retrieve themed Context
Summary:
We use `ViewManager.onMeasure` to perform measurements of Android views and pass the measured size back to Yoga. For Android in order to the report correct dimensions of a View, this View must be created using a Context that has a theme associated with it. Before, `onMeasure` only had ReactApplicationContext passed as the first parameter and ReactSwitch, for example, could not be measured correctly (because it uses the size of the thumb drawable, which is extracted from the current theme). This diff adds surfaceId as the first parameter of `FabricUIManager.measure`, so that we can retrieve ThemedReactContext and pass it to `ViewManager.onMeasure`.

The size of the Switch component is still incorrect, but at least the size reported back to Yoga is the same as in Paper. So there is more investigation necessary why this happens in Fabric. I will investigate and publish another diff with the fix.

Reviewed By: JoshuaGross, shergin

Differential Revision: D17625959

fbshipit-source-id: 48197a61240fb13042bef3e9f5d681acacc702fb
2019-10-03 03:15:20 -07:00

109 lines
3.4 KiB
C++

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SliderShadowNode.h"
#include "SliderLocalData.h"
#include <react/core/LayoutContext.h>
namespace facebook {
namespace react {
extern const char SliderComponentName[] = "Slider";
void SliderShadowNode::setImageManager(const SharedImageManager &imageManager) {
ensureUnsealed();
imageManager_ = imageManager;
}
void SliderShadowNode::setSliderMeasurementsManager(
const std::shared_ptr<SliderMeasurementsManager> &measurementsManager) {
ensureUnsealed();
measurementsManager_ = measurementsManager;
}
void SliderShadowNode::updateLocalData() {
const auto &newTrackImageSource = getTrackImageSource();
const auto &newMinimumTrackImageSource = getMinimumTrackImageSource();
const auto &newMaximumTrackImageSource = getMaximumTrackImageSource();
const auto &newThumbImageSource = getThumbImageSource();
const auto &localData = getLocalData();
if (localData) {
assert(std::dynamic_pointer_cast<const SliderLocalData>(localData));
auto currentLocalData =
std::static_pointer_cast<const SliderLocalData>(localData);
auto trackImageSource = currentLocalData->getTrackImageSource();
auto minimumTrackImageSource =
currentLocalData->getMinimumTrackImageSource();
auto maximumTrackImageSource =
currentLocalData->getMaximumTrackImageSource();
auto thumbImageSource = currentLocalData->getThumbImageSource();
bool anyChanged = newTrackImageSource != trackImageSource ||
newMinimumTrackImageSource != minimumTrackImageSource ||
newMaximumTrackImageSource != maximumTrackImageSource ||
newThumbImageSource != thumbImageSource;
if (!anyChanged) {
return;
}
}
// Now we are about to mutate the Shadow Node.
ensureUnsealed();
// It is not possible to copy or move image requests from SliderLocalData,
// so instead we recreate any image requests (that may already be in-flight?)
// TODO: check if multiple requests are cached or if it's a net loss
const auto &newLocalData = std::make_shared<SliderLocalData>(
newTrackImageSource,
imageManager_->requestImage(newTrackImageSource),
newMinimumTrackImageSource,
imageManager_->requestImage(newMinimumTrackImageSource),
newMaximumTrackImageSource,
imageManager_->requestImage(newMaximumTrackImageSource),
newThumbImageSource,
imageManager_->requestImage(newThumbImageSource));
setLocalData(newLocalData);
}
ImageSource SliderShadowNode::getTrackImageSource() const {
return getProps()->trackImage;
}
ImageSource SliderShadowNode::getMinimumTrackImageSource() const {
return getProps()->minimumTrackImage;
}
ImageSource SliderShadowNode::getMaximumTrackImageSource() const {
return getProps()->maximumTrackImage;
}
ImageSource SliderShadowNode::getThumbImageSource() const {
return getProps()->thumbImage;
}
#pragma mark - LayoutableShadowNode
Size SliderShadowNode::measure(LayoutConstraints layoutConstraints) const {
if (SliderMeasurementsManager::shouldMeasureSlider()) {
return measurementsManager_->measure(getSurfaceId(), layoutConstraints);
}
return {};
}
void SliderShadowNode::layout(LayoutContext layoutContext) {
updateLocalData();
ConcreteViewShadowNode::layout(layoutContext);
}
} // namespace react
} // namespace facebook