Summary: X-link: https://github.com/facebook/react-native/pull/42688 We are planning on overhauling NodeToString to output JSON instead of HTML for the purposes of better benchmarking and capturing trees in JSON format to benchmark later. This gives us a bit of a headache as we have to revise several build files to ensure this new library works, ensure that it is only included in certain debug builds, and deal with the benchmark <-> internal cross boundary that arises as the benchmark code (which is a separate binary) tries to interact with it. On top of it all this is really not used at all. The plan is to rip out this functionality and just put it in a separate binary that one can include if they really want to debug. That means that it cannot exist in the public API, so I am removing it here. Private internals come next Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D53137544
725 lines
23 KiB
Java
725 lines
23 KiB
Java
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
package com.facebook.yoga;
|
|
|
|
import com.facebook.yoga.annotations.DoNotStrip;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import javax.annotation.Nullable;
|
|
|
|
@DoNotStrip
|
|
public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
|
|
|
|
/* Those flags needs be in sync with YGJNI.h */
|
|
private static final byte MARGIN = 1;
|
|
private static final byte PADDING = 2;
|
|
private static final byte BORDER = 4;
|
|
private static final byte HAS_NEW_LAYOUT = 16;
|
|
|
|
private static final byte LAYOUT_EDGE_SET_FLAG_INDEX = 0;
|
|
private static final byte LAYOUT_WIDTH_INDEX = 1;
|
|
private static final byte LAYOUT_HEIGHT_INDEX = 2;
|
|
private static final byte LAYOUT_LEFT_INDEX = 3;
|
|
private static final byte LAYOUT_TOP_INDEX = 4;
|
|
private static final byte LAYOUT_DIRECTION_INDEX = 5;
|
|
private static final byte LAYOUT_MARGIN_START_INDEX = 6;
|
|
private static final byte LAYOUT_PADDING_START_INDEX = 10;
|
|
private static final byte LAYOUT_BORDER_START_INDEX = 14;
|
|
|
|
@Nullable private YogaNodeJNIBase mOwner;
|
|
@Nullable private List<YogaNodeJNIBase> mChildren;
|
|
@Nullable private YogaMeasureFunction mMeasureFunction;
|
|
@Nullable private YogaBaselineFunction mBaselineFunction;
|
|
protected long mNativePointer;
|
|
@Nullable private Object mData;
|
|
|
|
@DoNotStrip private @Nullable float[] arr = null;
|
|
|
|
@DoNotStrip private int mLayoutDirection = 0;
|
|
|
|
private boolean mHasNewLayout = true;
|
|
|
|
private YogaNodeJNIBase(long nativePointer) {
|
|
if (nativePointer == 0) {
|
|
throw new IllegalStateException("Failed to allocate native memory");
|
|
}
|
|
mNativePointer = nativePointer;
|
|
}
|
|
|
|
YogaNodeJNIBase() {
|
|
this(YogaNative.jni_YGNodeNewJNI());
|
|
}
|
|
|
|
YogaNodeJNIBase(YogaConfig config) {
|
|
this(YogaNative.jni_YGNodeNewWithConfigJNI(((YogaConfigJNIBase) config).mNativePointer));
|
|
}
|
|
|
|
public void reset() {
|
|
mMeasureFunction = null;
|
|
mBaselineFunction = null;
|
|
mData = null;
|
|
arr = null;
|
|
mHasNewLayout = true;
|
|
mLayoutDirection = 0;
|
|
|
|
YogaNative.jni_YGNodeResetJNI(mNativePointer);
|
|
}
|
|
|
|
public int getChildCount() {
|
|
return mChildren == null ? 0 : mChildren.size();
|
|
}
|
|
|
|
public YogaNodeJNIBase getChildAt(int i) {
|
|
if (mChildren == null) {
|
|
throw new IllegalStateException("YogaNode does not have children");
|
|
}
|
|
return mChildren.get(i);
|
|
}
|
|
|
|
public void addChildAt(YogaNode c, int i) {
|
|
if (!(c instanceof YogaNodeJNIBase)) {
|
|
return;
|
|
}
|
|
YogaNodeJNIBase child = (YogaNodeJNIBase) c;
|
|
if (child.mOwner != null) {
|
|
throw new IllegalStateException("Child already has a parent, it must be removed first.");
|
|
}
|
|
|
|
if (mChildren == null) {
|
|
mChildren = new ArrayList<>(4);
|
|
}
|
|
mChildren.add(i, child);
|
|
child.mOwner = this;
|
|
YogaNative.jni_YGNodeInsertChildJNI(mNativePointer, child.mNativePointer, i);
|
|
}
|
|
|
|
public void setIsReferenceBaseline(boolean isReferenceBaseline) {
|
|
YogaNative.jni_YGNodeSetIsReferenceBaselineJNI(mNativePointer, isReferenceBaseline);
|
|
}
|
|
|
|
public boolean isReferenceBaseline() {
|
|
return YogaNative.jni_YGNodeIsReferenceBaselineJNI(mNativePointer);
|
|
}
|
|
|
|
public void swapChildAt(YogaNode newChild, int position) {
|
|
if (!(newChild instanceof YogaNodeJNIBase)) {
|
|
return;
|
|
}
|
|
YogaNodeJNIBase child = (YogaNodeJNIBase) newChild;
|
|
mChildren.remove(position);
|
|
mChildren.add(position, child);
|
|
child.mOwner = this;
|
|
YogaNative.jni_YGNodeSwapChildJNI(mNativePointer, child.mNativePointer, position);
|
|
}
|
|
|
|
@Override
|
|
public YogaNodeJNIBase cloneWithChildren() {
|
|
try {
|
|
YogaNodeJNIBase clonedYogaNode = (YogaNodeJNIBase) super.clone();
|
|
if (clonedYogaNode.mChildren != null) {
|
|
clonedYogaNode.mChildren = new ArrayList<>(clonedYogaNode.mChildren);
|
|
}
|
|
long clonedNativePointer = YogaNative.jni_YGNodeCloneJNI(mNativePointer);
|
|
clonedYogaNode.mOwner = null;
|
|
clonedYogaNode.mNativePointer = clonedNativePointer;
|
|
for (int i = 0; i < clonedYogaNode.getChildCount(); i++) {
|
|
clonedYogaNode.swapChildAt(clonedYogaNode.getChildAt(i).cloneWithChildren(), i);
|
|
}
|
|
|
|
return clonedYogaNode;
|
|
} catch (CloneNotSupportedException ex) {
|
|
// This class implements Cloneable, this should not happen
|
|
throw new RuntimeException(ex);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public YogaNodeJNIBase cloneWithoutChildren() {
|
|
try {
|
|
YogaNodeJNIBase clonedYogaNode = (YogaNodeJNIBase) super.clone();
|
|
long clonedNativePointer = YogaNative.jni_YGNodeCloneJNI(mNativePointer);
|
|
clonedYogaNode.mOwner = null;
|
|
clonedYogaNode.mNativePointer = clonedNativePointer;
|
|
clonedYogaNode.clearChildren();
|
|
return clonedYogaNode;
|
|
} catch (CloneNotSupportedException ex) {
|
|
// This class implements Cloneable, this should not happen
|
|
throw new RuntimeException(ex);
|
|
}
|
|
}
|
|
|
|
private void clearChildren() {
|
|
mChildren = null;
|
|
YogaNative.jni_YGNodeRemoveAllChildrenJNI(mNativePointer);
|
|
}
|
|
|
|
public YogaNodeJNIBase removeChildAt(int i) {
|
|
if (mChildren == null) {
|
|
throw new IllegalStateException(
|
|
"Trying to remove a child of a YogaNode that does not have children");
|
|
}
|
|
final YogaNodeJNIBase child = mChildren.remove(i);
|
|
child.mOwner = null;
|
|
YogaNative.jni_YGNodeRemoveChildJNI(mNativePointer, child.mNativePointer);
|
|
return child;
|
|
}
|
|
|
|
/**
|
|
* The owner is used to identify the YogaTree that a {@link YogaNode} belongs to. This method will
|
|
* return the parent of the {@link YogaNode} when the {@link YogaNode} only belongs to one
|
|
* YogaTree or null when the {@link YogaNode} is shared between two or more YogaTrees.
|
|
*
|
|
* @return the {@link YogaNode} that owns this {@link YogaNode}.
|
|
*/
|
|
@Nullable
|
|
public YogaNodeJNIBase getOwner() {
|
|
return mOwner;
|
|
}
|
|
|
|
/** @deprecated Use #getOwner() instead. This will be removed in the next version. */
|
|
@Deprecated
|
|
@Nullable
|
|
public YogaNodeJNIBase getParent() {
|
|
return getOwner();
|
|
}
|
|
|
|
public int indexOf(YogaNode child) {
|
|
return mChildren == null ? -1 : mChildren.indexOf(child);
|
|
}
|
|
|
|
public void calculateLayout(float width, float height) {
|
|
long[] nativePointers = null;
|
|
YogaNodeJNIBase[] nodes = null;
|
|
|
|
freeze(null);
|
|
|
|
ArrayList<YogaNodeJNIBase> n = new ArrayList<>();
|
|
n.add(this);
|
|
for (int i = 0; i < n.size(); ++i) {
|
|
final YogaNodeJNIBase parent = n.get(i);
|
|
List<YogaNodeJNIBase> children = parent.mChildren;
|
|
if (children != null) {
|
|
for (YogaNodeJNIBase child : children) {
|
|
child.freeze(parent);
|
|
n.add(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
nodes = n.toArray(new YogaNodeJNIBase[n.size()]);
|
|
nativePointers = new long[nodes.length];
|
|
for (int i = 0; i < nodes.length; ++i) {
|
|
nativePointers[i] = nodes[i].mNativePointer;
|
|
}
|
|
|
|
YogaNative.jni_YGNodeCalculateLayoutJNI(mNativePointer, width, height, nativePointers, nodes);
|
|
}
|
|
|
|
private void freeze(YogaNode parent) {
|
|
Object data = getData();
|
|
if (data instanceof Inputs) {
|
|
((Inputs) data).freeze(this, parent);
|
|
}
|
|
}
|
|
|
|
public void dirty() {
|
|
YogaNative.jni_YGNodeMarkDirtyJNI(mNativePointer);
|
|
}
|
|
|
|
public boolean isDirty() {
|
|
return YogaNative.jni_YGNodeIsDirtyJNI(mNativePointer);
|
|
}
|
|
|
|
@Override
|
|
public void copyStyle(YogaNode srcNode) {
|
|
if (!(srcNode instanceof YogaNodeJNIBase)) {
|
|
return;
|
|
}
|
|
YogaNative.jni_YGNodeCopyStyleJNI(mNativePointer, ((YogaNodeJNIBase) srcNode).mNativePointer);
|
|
}
|
|
|
|
public YogaDirection getStyleDirection() {
|
|
return YogaDirection.fromInt(YogaNative.jni_YGNodeStyleGetDirectionJNI(mNativePointer));
|
|
}
|
|
|
|
public void setDirection(YogaDirection direction) {
|
|
YogaNative.jni_YGNodeStyleSetDirectionJNI(mNativePointer, direction.intValue());
|
|
}
|
|
|
|
public YogaFlexDirection getFlexDirection() {
|
|
return YogaFlexDirection.fromInt(YogaNative.jni_YGNodeStyleGetFlexDirectionJNI(mNativePointer));
|
|
}
|
|
|
|
public void setFlexDirection(YogaFlexDirection flexDirection) {
|
|
YogaNative.jni_YGNodeStyleSetFlexDirectionJNI(mNativePointer, flexDirection.intValue());
|
|
}
|
|
|
|
public YogaJustify getJustifyContent() {
|
|
return YogaJustify.fromInt(YogaNative.jni_YGNodeStyleGetJustifyContentJNI(mNativePointer));
|
|
}
|
|
|
|
public void setJustifyContent(YogaJustify justifyContent) {
|
|
YogaNative.jni_YGNodeStyleSetJustifyContentJNI(mNativePointer, justifyContent.intValue());
|
|
}
|
|
|
|
public YogaAlign getAlignItems() {
|
|
return YogaAlign.fromInt(YogaNative.jni_YGNodeStyleGetAlignItemsJNI(mNativePointer));
|
|
}
|
|
|
|
public void setAlignItems(YogaAlign alignItems) {
|
|
YogaNative.jni_YGNodeStyleSetAlignItemsJNI(mNativePointer, alignItems.intValue());
|
|
}
|
|
|
|
public YogaAlign getAlignSelf() {
|
|
return YogaAlign.fromInt(YogaNative.jni_YGNodeStyleGetAlignSelfJNI(mNativePointer));
|
|
}
|
|
|
|
public void setAlignSelf(YogaAlign alignSelf) {
|
|
YogaNative.jni_YGNodeStyleSetAlignSelfJNI(mNativePointer, alignSelf.intValue());
|
|
}
|
|
|
|
public YogaAlign getAlignContent() {
|
|
return YogaAlign.fromInt(YogaNative.jni_YGNodeStyleGetAlignContentJNI(mNativePointer));
|
|
}
|
|
|
|
public void setAlignContent(YogaAlign alignContent) {
|
|
YogaNative.jni_YGNodeStyleSetAlignContentJNI(mNativePointer, alignContent.intValue());
|
|
}
|
|
|
|
public YogaPositionType getPositionType() {
|
|
return YogaPositionType.fromInt(YogaNative.jni_YGNodeStyleGetPositionTypeJNI(mNativePointer));
|
|
}
|
|
|
|
public void setPositionType(YogaPositionType positionType) {
|
|
YogaNative.jni_YGNodeStyleSetPositionTypeJNI(mNativePointer, positionType.intValue());
|
|
}
|
|
|
|
public YogaWrap getWrap() {
|
|
return YogaWrap.fromInt(YogaNative.jni_YGNodeStyleGetFlexWrapJNI(mNativePointer));
|
|
}
|
|
|
|
public void setWrap(YogaWrap flexWrap) {
|
|
YogaNative.jni_YGNodeStyleSetFlexWrapJNI(mNativePointer, flexWrap.intValue());
|
|
}
|
|
|
|
public YogaOverflow getOverflow() {
|
|
return YogaOverflow.fromInt(YogaNative.jni_YGNodeStyleGetOverflowJNI(mNativePointer));
|
|
}
|
|
|
|
public void setOverflow(YogaOverflow overflow) {
|
|
YogaNative.jni_YGNodeStyleSetOverflowJNI(mNativePointer, overflow.intValue());
|
|
}
|
|
|
|
public YogaDisplay getDisplay() {
|
|
return YogaDisplay.fromInt(YogaNative.jni_YGNodeStyleGetDisplayJNI(mNativePointer));
|
|
}
|
|
|
|
public void setDisplay(YogaDisplay display) {
|
|
YogaNative.jni_YGNodeStyleSetDisplayJNI(mNativePointer, display.intValue());
|
|
}
|
|
|
|
public float getFlex() {
|
|
return YogaNative.jni_YGNodeStyleGetFlexJNI(mNativePointer);
|
|
}
|
|
|
|
public void setFlex(float flex) {
|
|
YogaNative.jni_YGNodeStyleSetFlexJNI(mNativePointer, flex);
|
|
}
|
|
|
|
public float getFlexGrow() {
|
|
return YogaNative.jni_YGNodeStyleGetFlexGrowJNI(mNativePointer);
|
|
}
|
|
|
|
public void setFlexGrow(float flexGrow) {
|
|
YogaNative.jni_YGNodeStyleSetFlexGrowJNI(mNativePointer, flexGrow);
|
|
}
|
|
|
|
public float getFlexShrink() {
|
|
return YogaNative.jni_YGNodeStyleGetFlexShrinkJNI(mNativePointer);
|
|
}
|
|
|
|
public void setFlexShrink(float flexShrink) {
|
|
YogaNative.jni_YGNodeStyleSetFlexShrinkJNI(mNativePointer, flexShrink);
|
|
}
|
|
|
|
public YogaValue getFlexBasis() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetFlexBasisJNI(mNativePointer));
|
|
}
|
|
|
|
public void setFlexBasis(float flexBasis) {
|
|
YogaNative.jni_YGNodeStyleSetFlexBasisJNI(mNativePointer, flexBasis);
|
|
}
|
|
|
|
public void setFlexBasisPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetFlexBasisPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public void setFlexBasisAuto() {
|
|
YogaNative.jni_YGNodeStyleSetFlexBasisAutoJNI(mNativePointer);
|
|
}
|
|
|
|
public YogaValue getMargin(YogaEdge edge) {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetMarginJNI(mNativePointer, edge.intValue()));
|
|
}
|
|
|
|
public void setMargin(YogaEdge edge, float margin) {
|
|
YogaNative.jni_YGNodeStyleSetMarginJNI(mNativePointer, edge.intValue(), margin);
|
|
}
|
|
|
|
public void setMarginPercent(YogaEdge edge, float percent) {
|
|
YogaNative.jni_YGNodeStyleSetMarginPercentJNI(mNativePointer, edge.intValue(), percent);
|
|
}
|
|
|
|
public void setMarginAuto(YogaEdge edge) {
|
|
YogaNative.jni_YGNodeStyleSetMarginAutoJNI(mNativePointer, edge.intValue());
|
|
}
|
|
|
|
public YogaValue getPadding(YogaEdge edge) {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetPaddingJNI(mNativePointer, edge.intValue()));
|
|
}
|
|
|
|
public void setPadding(YogaEdge edge, float padding) {
|
|
YogaNative.jni_YGNodeStyleSetPaddingJNI(mNativePointer, edge.intValue(), padding);
|
|
}
|
|
|
|
public void setPaddingPercent(YogaEdge edge, float percent) {
|
|
YogaNative.jni_YGNodeStyleSetPaddingPercentJNI(mNativePointer, edge.intValue(), percent);
|
|
}
|
|
|
|
public float getBorder(YogaEdge edge) {
|
|
return YogaNative.jni_YGNodeStyleGetBorderJNI(mNativePointer, edge.intValue());
|
|
}
|
|
|
|
public void setBorder(YogaEdge edge, float border) {
|
|
YogaNative.jni_YGNodeStyleSetBorderJNI(mNativePointer, edge.intValue(), border);
|
|
}
|
|
|
|
public YogaValue getPosition(YogaEdge edge) {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetPositionJNI(mNativePointer, edge.intValue()));
|
|
}
|
|
|
|
public void setPosition(YogaEdge edge, float position) {
|
|
YogaNative.jni_YGNodeStyleSetPositionJNI(mNativePointer, edge.intValue(), position);
|
|
}
|
|
|
|
public void setPositionPercent(YogaEdge edge, float percent) {
|
|
YogaNative.jni_YGNodeStyleSetPositionPercentJNI(mNativePointer, edge.intValue(), percent);
|
|
}
|
|
|
|
public YogaValue getWidth() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetWidthJNI(mNativePointer));
|
|
}
|
|
|
|
public void setWidth(float width) {
|
|
YogaNative.jni_YGNodeStyleSetWidthJNI(mNativePointer, width);
|
|
}
|
|
|
|
public void setWidthPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetWidthPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public void setWidthAuto() {
|
|
YogaNative.jni_YGNodeStyleSetWidthAutoJNI(mNativePointer);
|
|
}
|
|
|
|
public YogaValue getHeight() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetHeightJNI(mNativePointer));
|
|
}
|
|
|
|
public void setHeight(float height) {
|
|
YogaNative.jni_YGNodeStyleSetHeightJNI(mNativePointer, height);
|
|
}
|
|
|
|
public void setHeightPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetHeightPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public void setHeightAuto() {
|
|
YogaNative.jni_YGNodeStyleSetHeightAutoJNI(mNativePointer);
|
|
}
|
|
|
|
public YogaValue getMinWidth() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinWidthJNI(mNativePointer));
|
|
}
|
|
|
|
public void setMinWidth(float minWidth) {
|
|
YogaNative.jni_YGNodeStyleSetMinWidthJNI(mNativePointer, minWidth);
|
|
}
|
|
|
|
public void setMinWidthPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetMinWidthPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public YogaValue getMinHeight() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinHeightJNI(mNativePointer));
|
|
}
|
|
|
|
public void setMinHeight(float minHeight) {
|
|
YogaNative.jni_YGNodeStyleSetMinHeightJNI(mNativePointer, minHeight);
|
|
}
|
|
|
|
public void setMinHeightPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetMinHeightPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public YogaValue getMaxWidth() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxWidthJNI(mNativePointer));
|
|
}
|
|
|
|
public void setMaxWidth(float maxWidth) {
|
|
YogaNative.jni_YGNodeStyleSetMaxWidthJNI(mNativePointer, maxWidth);
|
|
}
|
|
|
|
public void setMaxWidthPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetMaxWidthPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public YogaValue getMaxHeight() {
|
|
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxHeightJNI(mNativePointer));
|
|
}
|
|
|
|
public void setMaxHeight(float maxheight) {
|
|
YogaNative.jni_YGNodeStyleSetMaxHeightJNI(mNativePointer, maxheight);
|
|
}
|
|
|
|
public void setMaxHeightPercent(float percent) {
|
|
YogaNative.jni_YGNodeStyleSetMaxHeightPercentJNI(mNativePointer, percent);
|
|
}
|
|
|
|
public float getAspectRatio() {
|
|
return YogaNative.jni_YGNodeStyleGetAspectRatioJNI(mNativePointer);
|
|
}
|
|
|
|
public void setAspectRatio(float aspectRatio) {
|
|
YogaNative.jni_YGNodeStyleSetAspectRatioJNI(mNativePointer, aspectRatio);
|
|
}
|
|
|
|
public void setMeasureFunction(YogaMeasureFunction measureFunction) {
|
|
mMeasureFunction = measureFunction;
|
|
YogaNative.jni_YGNodeSetHasMeasureFuncJNI(mNativePointer, measureFunction != null);
|
|
}
|
|
|
|
@Override
|
|
public void setAlwaysFormsContainingBlock(boolean alwaysFormsContainingBlock) {
|
|
YogaNative.jni_YGNodeSetAlwaysFormsContainingBlockJNI(mNativePointer, alwaysFormsContainingBlock);
|
|
}
|
|
|
|
// Implementation Note: Why this method needs to stay final
|
|
//
|
|
// We cache the jmethodid for this method in Yoga code. This means that even if a subclass
|
|
// were to override measure, we'd still call this implementation from layout code since the
|
|
// overriding method will have a different jmethodid. This is final to prevent that mistake.
|
|
@DoNotStrip
|
|
public final long measure(float width, int widthMode, float height, int heightMode) {
|
|
if (!isMeasureDefined()) {
|
|
throw new RuntimeException("Measure function isn't defined!");
|
|
}
|
|
|
|
return mMeasureFunction.measure(
|
|
this,
|
|
width,
|
|
YogaMeasureMode.fromInt(widthMode),
|
|
height,
|
|
YogaMeasureMode.fromInt(heightMode));
|
|
}
|
|
|
|
public void setBaselineFunction(YogaBaselineFunction baselineFunction) {
|
|
mBaselineFunction = baselineFunction;
|
|
YogaNative.jni_YGNodeSetHasBaselineFuncJNI(mNativePointer, baselineFunction != null);
|
|
}
|
|
|
|
@DoNotStrip
|
|
public final float baseline(float width, float height) {
|
|
return mBaselineFunction.baseline(this, width, height);
|
|
}
|
|
|
|
public boolean isMeasureDefined() {
|
|
return mMeasureFunction != null;
|
|
}
|
|
|
|
@Override
|
|
public boolean isBaselineDefined() {
|
|
return mBaselineFunction != null;
|
|
}
|
|
|
|
public void setData(Object data) {
|
|
mData = data;
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Object getData() {
|
|
return mData;
|
|
}
|
|
|
|
/**
|
|
* This method replaces the child at childIndex position with the newNode received by parameter.
|
|
* This is different than calling removeChildAt and addChildAt because this method ONLY replaces
|
|
* the child in the mChildren datastructure. @DoNotStrip: called from JNI
|
|
*
|
|
* @return the nativePointer of the newNode {@link YogaNode}
|
|
*/
|
|
@DoNotStrip
|
|
private final long replaceChild(YogaNodeJNIBase newNode, int childIndex) {
|
|
if (mChildren == null) {
|
|
throw new IllegalStateException("Cannot replace child. YogaNode does not have children");
|
|
}
|
|
mChildren.remove(childIndex);
|
|
mChildren.add(childIndex, newNode);
|
|
newNode.mOwner = this;
|
|
return newNode.mNativePointer;
|
|
}
|
|
|
|
private static YogaValue valueFromLong(long raw) {
|
|
return new YogaValue(Float.intBitsToFloat((int) raw), (int) (raw >> 32));
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutX() {
|
|
return arr != null ? arr[LAYOUT_LEFT_INDEX] : 0;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutY() {
|
|
return arr != null ? arr[LAYOUT_TOP_INDEX] : 0;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutWidth() {
|
|
return arr != null ? arr[LAYOUT_WIDTH_INDEX] : 0;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutHeight() {
|
|
return arr != null ? arr[LAYOUT_HEIGHT_INDEX] : 0;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutMargin(YogaEdge edge) {
|
|
if (arr != null && ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) {
|
|
switch (edge) {
|
|
case LEFT:
|
|
return arr[LAYOUT_MARGIN_START_INDEX];
|
|
case TOP:
|
|
return arr[LAYOUT_MARGIN_START_INDEX + 1];
|
|
case RIGHT:
|
|
return arr[LAYOUT_MARGIN_START_INDEX + 2];
|
|
case BOTTOM:
|
|
return arr[LAYOUT_MARGIN_START_INDEX + 3];
|
|
case START:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[LAYOUT_MARGIN_START_INDEX + 2]
|
|
: arr[LAYOUT_MARGIN_START_INDEX];
|
|
case END:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[LAYOUT_MARGIN_START_INDEX]
|
|
: arr[LAYOUT_MARGIN_START_INDEX + 2];
|
|
default:
|
|
throw new IllegalArgumentException("Cannot get layout margins of multi-edge shorthands");
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutPadding(YogaEdge edge) {
|
|
if (arr != null && ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & PADDING) == PADDING) {
|
|
int paddingStartIndex =
|
|
LAYOUT_PADDING_START_INDEX
|
|
- ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4);
|
|
switch (edge) {
|
|
case LEFT:
|
|
return arr[paddingStartIndex];
|
|
case TOP:
|
|
return arr[paddingStartIndex + 1];
|
|
case RIGHT:
|
|
return arr[paddingStartIndex + 2];
|
|
case BOTTOM:
|
|
return arr[paddingStartIndex + 3];
|
|
case START:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[paddingStartIndex + 2]
|
|
: arr[paddingStartIndex];
|
|
case END:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[paddingStartIndex]
|
|
: arr[paddingStartIndex + 2];
|
|
default:
|
|
throw new IllegalArgumentException("Cannot get layout paddings of multi-edge shorthands");
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutBorder(YogaEdge edge) {
|
|
if (arr != null && ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & BORDER) == BORDER) {
|
|
int borderStartIndex =
|
|
LAYOUT_BORDER_START_INDEX
|
|
- ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4)
|
|
- ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & PADDING) == PADDING) ? 0 : 4);
|
|
switch (edge) {
|
|
case LEFT:
|
|
return arr[borderStartIndex];
|
|
case TOP:
|
|
return arr[borderStartIndex + 1];
|
|
case RIGHT:
|
|
return arr[borderStartIndex + 2];
|
|
case BOTTOM:
|
|
return arr[borderStartIndex + 3];
|
|
case START:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[borderStartIndex + 2]
|
|
: arr[borderStartIndex];
|
|
case END:
|
|
return getLayoutDirection() == YogaDirection.RTL
|
|
? arr[borderStartIndex]
|
|
: arr[borderStartIndex + 2];
|
|
default:
|
|
throw new IllegalArgumentException("Cannot get layout border of multi-edge shorthands");
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public YogaDirection getLayoutDirection() {
|
|
return YogaDirection.fromInt(
|
|
arr != null ? (int) arr[LAYOUT_DIRECTION_INDEX] : mLayoutDirection);
|
|
}
|
|
|
|
@Override
|
|
public boolean hasNewLayout() {
|
|
if (arr != null) {
|
|
return (((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX]) & HAS_NEW_LAYOUT) == HAS_NEW_LAYOUT;
|
|
} else {
|
|
return mHasNewLayout;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void markLayoutSeen() {
|
|
if (arr != null) {
|
|
arr[LAYOUT_EDGE_SET_FLAG_INDEX] = ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX]) & ~(HAS_NEW_LAYOUT);
|
|
}
|
|
mHasNewLayout = false;
|
|
}
|
|
|
|
@Override
|
|
public float getGap(YogaGutter gutter) {
|
|
return YogaNative.jni_YGNodeStyleGetGapJNI(mNativePointer, gutter.intValue());
|
|
}
|
|
|
|
@Override
|
|
public void setGap(YogaGutter gutter, float gapLength) {
|
|
YogaNative.jni_YGNodeStyleSetGapJNI(mNativePointer, gutter.intValue(), gapLength);
|
|
}
|
|
}
|