Summary: Keeping enums in sync between all the different bindings is tedious and error prone. Getting one of the values in the incorrect order could lead to many hours of debugging as they are passed as ints to C. This diff adds a simple python script to generate these enums for all languages. This also makes it much easier to add support for more languages in the future Reviewed By: gkassabli Differential Revision: D4174263 fbshipit-source-id: 478961a8f683e196704d3c6ea1505a05c85fcb10
544 lines
16 KiB
Java
544 lines
16 KiB
Java
/**
|
|
* 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.
|
|
*/
|
|
|
|
package com.facebook.csslayout;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import java.util.List;
|
|
import java.util.ArrayList;
|
|
|
|
import com.facebook.proguard.annotations.DoNotStrip;
|
|
import com.facebook.soloader.SoLoader;
|
|
|
|
public class CSSNode implements CSSNodeAPI<CSSNode> {
|
|
|
|
static {
|
|
try {
|
|
SoLoader.loadLibrary("csslayout");
|
|
} catch (Exception ignored) {
|
|
// The user probably didn't call SoLoader.init(). Fall back to System.loadLibrary() instead.
|
|
System.out.println("Falling back to System.loadLibrary()");
|
|
System.loadLibrary("csslayout");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get native instance count. Useful for testing only.
|
|
*/
|
|
static native int jni_CSSNodeGetInstanceCount();
|
|
static native void jni_CSSLog(int level, String message);
|
|
|
|
private static native void jni_CSSLayoutSetLogger(Object logger);
|
|
public static void setLogger(CSSLogger logger) {
|
|
jni_CSSLayoutSetLogger(logger);
|
|
}
|
|
|
|
private static native void jni_CSSLayoutSetExperimentalFeatureEnabled(
|
|
int feature,
|
|
boolean enabled);
|
|
public static void setExperimentalFeatureEnabled(
|
|
CSSExperimentalFeature feature,
|
|
boolean enabled) {
|
|
jni_CSSLayoutSetExperimentalFeatureEnabled(feature.intValue(), enabled);
|
|
}
|
|
|
|
private static native boolean jni_CSSLayoutIsExperimentalFeatureEnabled(int feature);
|
|
public static boolean isExperimentalFeatureEnabled(CSSExperimentalFeature feature) {
|
|
return jni_CSSLayoutIsExperimentalFeatureEnabled(feature.intValue());
|
|
}
|
|
|
|
private CSSNode mParent;
|
|
private List<CSSNode> mChildren;
|
|
private MeasureFunction mMeasureFunction;
|
|
private long mNativePointer;
|
|
private Object mData;
|
|
|
|
private boolean mHasSetPadding = false;
|
|
private boolean mHasSetMargin = false;
|
|
private boolean mHasSetBorder = false;
|
|
private boolean mHasSetPosition = false;
|
|
|
|
@DoNotStrip
|
|
private float mWidth = CSSConstants.UNDEFINED;
|
|
@DoNotStrip
|
|
private float mHeight = CSSConstants.UNDEFINED;
|
|
@DoNotStrip
|
|
private float mTop = CSSConstants.UNDEFINED;
|
|
@DoNotStrip
|
|
private float mLeft = CSSConstants.UNDEFINED;
|
|
@DoNotStrip
|
|
private int mLayoutDirection = 0;
|
|
|
|
private native long jni_CSSNodeNew();
|
|
public CSSNode() {
|
|
mNativePointer = jni_CSSNodeNew();
|
|
if (mNativePointer == 0) {
|
|
throw new IllegalStateException("Failed to allocate native memory");
|
|
}
|
|
}
|
|
|
|
private native void jni_CSSNodeFree(long nativePointer);
|
|
@Override
|
|
protected void finalize() throws Throwable {
|
|
try {
|
|
jni_CSSNodeFree(mNativePointer);
|
|
} finally {
|
|
super.finalize();
|
|
}
|
|
}
|
|
|
|
private native void jni_CSSNodeReset(long nativePointer);
|
|
@Override
|
|
public void reset() {
|
|
mHasSetPadding = false;
|
|
mHasSetMargin = false;
|
|
mHasSetBorder = false;
|
|
mHasSetPosition = false;
|
|
|
|
mWidth = CSSConstants.UNDEFINED;
|
|
mHeight = CSSConstants.UNDEFINED;
|
|
mTop = CSSConstants.UNDEFINED;
|
|
mLeft = CSSConstants.UNDEFINED;
|
|
mLayoutDirection = 0;
|
|
|
|
mMeasureFunction = null;
|
|
mData = null;
|
|
|
|
jni_CSSNodeReset(mNativePointer);
|
|
}
|
|
|
|
@Override
|
|
public int getChildCount() {
|
|
return mChildren == null ? 0 : mChildren.size();
|
|
}
|
|
|
|
@Override
|
|
public CSSNode getChildAt(int i) {
|
|
return mChildren.get(i);
|
|
}
|
|
|
|
private native void jni_CSSNodeInsertChild(long nativePointer, long childPointer, int index);
|
|
@Override
|
|
public void addChildAt(CSSNode child, int i) {
|
|
if (child.mParent != 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.mParent = this;
|
|
jni_CSSNodeInsertChild(mNativePointer, child.mNativePointer, i);
|
|
}
|
|
|
|
private native void jni_CSSNodeRemoveChild(long nativePointer, long childPointer);
|
|
@Override
|
|
public CSSNode removeChildAt(int i) {
|
|
|
|
final CSSNode child = mChildren.remove(i);
|
|
child.mParent = null;
|
|
jni_CSSNodeRemoveChild(mNativePointer, child.mNativePointer);
|
|
return child;
|
|
}
|
|
|
|
@Override
|
|
public @Nullable
|
|
CSSNode getParent() {
|
|
return mParent;
|
|
}
|
|
|
|
@Override
|
|
public int indexOf(CSSNode child) {
|
|
return mChildren == null ? -1 : mChildren.indexOf(child);
|
|
}
|
|
|
|
private native void jni_CSSNodeCalculateLayout(long nativePointer);
|
|
@Override
|
|
public void calculateLayout(CSSLayoutContext layoutContext) {
|
|
jni_CSSNodeCalculateLayout(mNativePointer);
|
|
}
|
|
|
|
private native boolean jni_CSSNodeHasNewLayout(long nativePointer);
|
|
@Override
|
|
public boolean hasNewLayout() {
|
|
return jni_CSSNodeHasNewLayout(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeMarkDirty(long nativePointer);
|
|
@Override
|
|
public void dirty() {
|
|
jni_CSSNodeMarkDirty(mNativePointer);
|
|
}
|
|
|
|
private native boolean jni_CSSNodeIsDirty(long nativePointer);
|
|
@Override
|
|
public boolean isDirty() {
|
|
return jni_CSSNodeIsDirty(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeMarkLayoutSeen(long nativePointer);
|
|
@Override
|
|
public void markLayoutSeen() {
|
|
jni_CSSNodeMarkLayoutSeen(mNativePointer);
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetDirection(long nativePointer);
|
|
@Override
|
|
public CSSDirection getStyleDirection() {
|
|
return CSSDirection.values()[jni_CSSNodeStyleGetDirection(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetDirection(long nativePointer, int direction);
|
|
@Override
|
|
public void setDirection(CSSDirection direction) {
|
|
jni_CSSNodeStyleSetDirection(mNativePointer, direction.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetFlexDirection(long nativePointer);
|
|
@Override
|
|
public CSSFlexDirection getFlexDirection() {
|
|
return CSSFlexDirection.values()[jni_CSSNodeStyleGetFlexDirection(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlexDirection(long nativePointer, int flexDirection);
|
|
@Override
|
|
public void setFlexDirection(CSSFlexDirection flexDirection) {
|
|
jni_CSSNodeStyleSetFlexDirection(mNativePointer, flexDirection.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetJustifyContent(long nativePointer);
|
|
@Override
|
|
public CSSJustify getJustifyContent() {
|
|
return CSSJustify.values()[jni_CSSNodeStyleGetJustifyContent(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetJustifyContent(long nativePointer, int justifyContent);
|
|
@Override
|
|
public void setJustifyContent(CSSJustify justifyContent) {
|
|
jni_CSSNodeStyleSetJustifyContent(mNativePointer, justifyContent.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetAlignItems(long nativePointer);
|
|
@Override
|
|
public CSSAlign getAlignItems() {
|
|
return CSSAlign.values()[jni_CSSNodeStyleGetAlignItems(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetAlignItems(long nativePointer, int alignItems);
|
|
@Override
|
|
public void setAlignItems(CSSAlign alignItems) {
|
|
jni_CSSNodeStyleSetAlignItems(mNativePointer, alignItems.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetAlignSelf(long nativePointer);
|
|
@Override
|
|
public CSSAlign getAlignSelf() {
|
|
return CSSAlign.values()[jni_CSSNodeStyleGetAlignSelf(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetAlignSelf(long nativePointer, int alignSelf);
|
|
@Override
|
|
public void setAlignSelf(CSSAlign alignSelf) {
|
|
jni_CSSNodeStyleSetAlignSelf(mNativePointer, alignSelf.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetAlignContent(long nativePointer);
|
|
@Override
|
|
public CSSAlign getAlignContent() {
|
|
return CSSAlign.values()[jni_CSSNodeStyleGetAlignContent(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetAlignContent(long nativePointer, int alignContent);
|
|
@Override
|
|
public void setAlignContent(CSSAlign alignContent) {
|
|
jni_CSSNodeStyleSetAlignContent(mNativePointer, alignContent.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetPositionType(long nativePointer);
|
|
@Override
|
|
public CSSPositionType getPositionType() {
|
|
return CSSPositionType.values()[jni_CSSNodeStyleGetPositionType(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetPositionType(long nativePointer, int positionType);
|
|
@Override
|
|
public void setPositionType(CSSPositionType positionType) {
|
|
jni_CSSNodeStyleSetPositionType(mNativePointer, positionType.intValue());
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlexWrap(long nativePointer, int wrapType);
|
|
@Override
|
|
public void setWrap(CSSWrap flexWrap) {
|
|
jni_CSSNodeStyleSetFlexWrap(mNativePointer, flexWrap.intValue());
|
|
}
|
|
|
|
private native int jni_CSSNodeStyleGetOverflow(long nativePointer);
|
|
@Override
|
|
public CSSOverflow getOverflow() {
|
|
return CSSOverflow.values()[jni_CSSNodeStyleGetOverflow(mNativePointer)];
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetOverflow(long nativePointer, int overflow);
|
|
@Override
|
|
public void setOverflow(CSSOverflow overflow) {
|
|
jni_CSSNodeStyleSetOverflow(mNativePointer, overflow.intValue());
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlex(long nativePointer, float flex);
|
|
@Override
|
|
public void setFlex(float flex) {
|
|
jni_CSSNodeStyleSetFlex(mNativePointer, flex);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetFlexGrow(long nativePointer);
|
|
@Override
|
|
public float getFlexGrow() {
|
|
return jni_CSSNodeStyleGetFlexGrow(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlexGrow(long nativePointer, float flexGrow);
|
|
@Override
|
|
public void setFlexGrow(float flexGrow) {
|
|
jni_CSSNodeStyleSetFlexGrow(mNativePointer, flexGrow);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetFlexShrink(long nativePointer);
|
|
@Override
|
|
public float getFlexShrink() {
|
|
return jni_CSSNodeStyleGetFlexShrink(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlexShrink(long nativePointer, float flexShrink);
|
|
@Override
|
|
public void setFlexShrink(float flexShrink) {
|
|
jni_CSSNodeStyleSetFlexShrink(mNativePointer, flexShrink);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetFlexBasis(long nativePointer);
|
|
@Override
|
|
public float getFlexBasis() {
|
|
return jni_CSSNodeStyleGetFlexBasis(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetFlexBasis(long nativePointer, float flexBasis);
|
|
@Override
|
|
public void setFlexBasis(float flexBasis) {
|
|
jni_CSSNodeStyleSetFlexBasis(mNativePointer, flexBasis);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetMargin(long nativePointer, int edge);
|
|
@Override
|
|
public float getMargin(int spacingType) {
|
|
if (!mHasSetMargin) {
|
|
return spacingType < Spacing.START ? 0 : CSSConstants.UNDEFINED;
|
|
}
|
|
return jni_CSSNodeStyleGetMargin(mNativePointer, spacingType);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetMargin(long nativePointer, int edge, float margin);
|
|
@Override
|
|
public void setMargin(int spacingType, float margin) {
|
|
mHasSetMargin = true;
|
|
jni_CSSNodeStyleSetMargin(mNativePointer, spacingType, margin);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetPadding(long nativePointer, int edge);
|
|
@Override
|
|
public float getPadding(int spacingType) {
|
|
if (!mHasSetPadding) {
|
|
return spacingType < Spacing.START ? 0 : CSSConstants.UNDEFINED;
|
|
}
|
|
return jni_CSSNodeStyleGetPadding(mNativePointer, spacingType);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetPadding(long nativePointer, int edge, float padding);
|
|
@Override
|
|
public void setPadding(int spacingType, float padding) {
|
|
mHasSetPadding = true;
|
|
jni_CSSNodeStyleSetPadding(mNativePointer, spacingType, padding);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetBorder(long nativePointer, int edge);
|
|
@Override
|
|
public float getBorder(int spacingType) {
|
|
if (!mHasSetBorder) {
|
|
return spacingType < Spacing.START ? 0 : CSSConstants.UNDEFINED;
|
|
}
|
|
return jni_CSSNodeStyleGetBorder(mNativePointer, spacingType);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetBorder(long nativePointer, int edge, float border);
|
|
@Override
|
|
public void setBorder(int spacingType, float border) {
|
|
mHasSetBorder = true;
|
|
jni_CSSNodeStyleSetBorder(mNativePointer, spacingType, border);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetPosition(long nativePointer, int edge);
|
|
@Override
|
|
public float getPosition(int spacingType) {
|
|
if (!mHasSetPosition) {
|
|
return CSSConstants.UNDEFINED;
|
|
}
|
|
return jni_CSSNodeStyleGetPosition(mNativePointer, spacingType);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetPosition(long nativePointer, int edge, float position);
|
|
@Override
|
|
public void setPosition(int spacingType, float position) {
|
|
mHasSetPosition = true;
|
|
jni_CSSNodeStyleSetPosition(mNativePointer, spacingType, position);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetWidth(long nativePointer);
|
|
@Override
|
|
public float getStyleWidth() {
|
|
return jni_CSSNodeStyleGetWidth(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetWidth(long nativePointer, float width);
|
|
@Override
|
|
public void setStyleWidth(float width) {
|
|
jni_CSSNodeStyleSetWidth(mNativePointer, width);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetHeight(long nativePointer);
|
|
@Override
|
|
public float getStyleHeight() {
|
|
return jni_CSSNodeStyleGetHeight(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetHeight(long nativePointer, float height);
|
|
@Override
|
|
public void setStyleHeight(float height) {
|
|
jni_CSSNodeStyleSetHeight(mNativePointer, height);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetMinWidth(long nativePointer);
|
|
@Override
|
|
public float getStyleMinWidth() {
|
|
return jni_CSSNodeStyleGetMinWidth(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetMinWidth(long nativePointer, float minWidth);
|
|
@Override
|
|
public void setStyleMinWidth(float minWidth) {
|
|
jni_CSSNodeStyleSetMinWidth(mNativePointer, minWidth);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetMinHeight(long nativePointer);
|
|
@Override
|
|
public float getStyleMinHeight() {
|
|
return jni_CSSNodeStyleGetMinHeight(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetMinHeight(long nativePointer, float minHeight);
|
|
@Override
|
|
public void setStyleMinHeight(float minHeight) {
|
|
jni_CSSNodeStyleSetMinHeight(mNativePointer, minHeight);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetMaxWidth(long nativePointer);
|
|
@Override
|
|
public float getStyleMaxWidth() {
|
|
return jni_CSSNodeStyleGetMaxWidth(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetMaxWidth(long nativePointer, float maxWidth);
|
|
@Override
|
|
public void setStyleMaxWidth(float maxWidth) {
|
|
jni_CSSNodeStyleSetMaxWidth(mNativePointer, maxWidth);
|
|
}
|
|
|
|
private native float jni_CSSNodeStyleGetMaxHeight(long nativePointer);
|
|
@Override
|
|
public float getStyleMaxHeight() {
|
|
return jni_CSSNodeStyleGetMaxHeight(mNativePointer);
|
|
}
|
|
|
|
private native void jni_CSSNodeStyleSetMaxHeight(long nativePointer, float maxheight);
|
|
@Override
|
|
public void setStyleMaxHeight(float maxheight) {
|
|
jni_CSSNodeStyleSetMaxHeight(mNativePointer, maxheight);
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutX() {
|
|
return mLeft;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutY() {
|
|
return mTop;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutWidth() {
|
|
return mWidth;
|
|
}
|
|
|
|
@Override
|
|
public float getLayoutHeight() {
|
|
return mHeight;
|
|
}
|
|
|
|
@Override
|
|
public CSSDirection getLayoutDirection() {
|
|
return CSSDirection.values()[mLayoutDirection];
|
|
}
|
|
|
|
private native void jni_CSSNodeSetHasMeasureFunc(long nativePointer, boolean hasMeasureFunc);
|
|
@Override
|
|
public void setMeasureFunction(MeasureFunction measureFunction) {
|
|
mMeasureFunction = measureFunction;
|
|
jni_CSSNodeSetHasMeasureFunc(mNativePointer, measureFunction != null);
|
|
}
|
|
|
|
// Implementation Note: Why this method needs to stay final
|
|
//
|
|
// We cache the jmethodid for this method in CSSLayout 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,
|
|
CSSMeasureMode.values()[widthMode],
|
|
height,
|
|
CSSMeasureMode.values()[heightMode]);
|
|
}
|
|
|
|
@Override
|
|
public boolean isMeasureDefined() {
|
|
return mMeasureFunction != null;
|
|
}
|
|
|
|
@Override
|
|
public boolean valuesEqual(float f1, float f2) {
|
|
return FloatUtil.floatsEqual(f1, f2);
|
|
}
|
|
|
|
@Override
|
|
public void setData(Object data) {
|
|
mData = data;
|
|
}
|
|
|
|
@Override
|
|
public Object getData() {
|
|
return mData;
|
|
}
|
|
}
|