Add aspectRatio style property
Reviewed By: gkassabli Differential Revision: D4211458 fbshipit-source-id: f8d0d318369c7b529ee29e61a52b17d0cf3b396d
This commit is contained in:
parent
ec467fbd34
commit
e1df3c8782
|
@ -85,6 +85,9 @@ typedef struct CSSStyle {
|
|||
float dimensions[2];
|
||||
float minDimensions[2];
|
||||
float maxDimensions[2];
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
float aspectRatio;
|
||||
} CSSStyle;
|
||||
|
||||
typedef struct CSSNode {
|
||||
|
@ -269,6 +272,8 @@ void CSSNodeInit(const CSSNodeRef node) {
|
|||
node->style.border[edge] = CSSUndefined;
|
||||
}
|
||||
|
||||
node->style.aspectRatio = CSSUndefined;
|
||||
|
||||
node->layout.dimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
node->layout.dimensions[CSSDimensionHeight] = CSSUndefined;
|
||||
|
||||
|
@ -459,6 +464,9 @@ CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimen
|
|||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, AspectRatio, aspectRatio, aspectRatio);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSEdgeLeft]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSEdgeTop]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSEdgeRight]);
|
||||
|
@ -1032,6 +1040,20 @@ static void computeChildFlexBasis(const CSSNodeRef node,
|
|||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (!isMainAxisRow && childWidthMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
return;
|
||||
} else if (isMainAxisRow && childHeightMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
|
@ -1108,6 +1130,20 @@ static void absoluteLayoutChild(const CSSNodeRef node,
|
|||
}
|
||||
}
|
||||
|
||||
// Exactly one dimension needs to be defined for us to be able to do aspect ratio
|
||||
// calculation. One dimension being the anchor and the other being flexible.
|
||||
if (CSSValueIsUndefined(childWidth) ^ CSSValueIsUndefined(childHeight)) {
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (CSSValueIsUndefined(childWidth)) {
|
||||
childWidth = fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
} else if (CSSValueIsUndefined(childHeight)) {
|
||||
childHeight = fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're still missing one or the other dimension, measure the content.
|
||||
if (CSSValueIsUndefined(childWidth) || CSSValueIsUndefined(childHeight)) {
|
||||
childWidthMeasureMode =
|
||||
|
@ -1774,6 +1810,19 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||
}
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(currentRelativeChild->style.aspectRatio)) {
|
||||
if (isMainAxisRow && childHeightMeasureMode != CSSMeasureModeExactly) {
|
||||
childHeight =
|
||||
fmaxf(childWidth * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionColumn));
|
||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
} else if (!isMainAxisRow && childWidthMeasureMode != CSSMeasureModeExactly) {
|
||||
childWidth = fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionRow));
|
||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
|
|
|
@ -149,6 +149,15 @@ CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight);
|
|||
CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
// Aspect ratio control the size of the undefined dimension of a node.
|
||||
// - On a node with a set width/height aspect ratio control the size of the unset dimension
|
||||
// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if unset
|
||||
// - On a node with a measure function aspect ratio works as though the measure function measures the flex basis
|
||||
// - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if unset
|
||||
// - Aspect ratio takes min/max dimensions into account
|
||||
CSS_NODE_STYLE_PROPERTY(float, AspectRatio, aspectRatio);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Left);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Top);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Right);
|
||||
|
|
|
@ -476,6 +476,16 @@ public class CSSNode implements CSSNodeAPI<CSSNode> {
|
|||
jni_CSSNodeStyleSetMaxHeight(mNativePointer, maxheight);
|
||||
}
|
||||
|
||||
private native float jni_CSSNodeStyleGetAspectRatio(long nativePointer);
|
||||
public float getStyleAspectRatio() {
|
||||
return jni_CSSNodeStyleGetAspectRatio(mNativePointer);
|
||||
}
|
||||
|
||||
private native void jni_CSSNodeStyleSetAspectRatio(long nativePointer, float aspectRatio);
|
||||
public void setStyleAspectRatio(float aspectRatio) {
|
||||
jni_CSSNodeStyleSetAspectRatio(mNativePointer, aspectRatio);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getLayoutX() {
|
||||
return mLeft;
|
||||
|
|
|
@ -249,6 +249,9 @@ CSS_NODE_JNI_STYLE_PROP(jfloat, float, Height);
|
|||
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MinHeight);
|
||||
CSS_NODE_JNI_STYLE_PROP(jfloat, float, MaxHeight);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
CSS_NODE_JNI_STYLE_PROP(jfloat, float, AspectRatio);
|
||||
|
||||
#define CSSMakeNativeMethod(name) makeNativeMethod(#name, name)
|
||||
|
||||
jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||
|
@ -312,6 +315,8 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
|
|||
CSSMakeNativeMethod(jni_CSSNodeStyleSetMaxWidth),
|
||||
CSSMakeNativeMethod(jni_CSSNodeStyleGetMaxHeight),
|
||||
CSSMakeNativeMethod(jni_CSSNodeStyleSetMaxHeight),
|
||||
CSSMakeNativeMethod(jni_CSSNodeStyleGetAspectRatio),
|
||||
CSSMakeNativeMethod(jni_CSSNodeStyleSetAspectRatio),
|
||||
|
||||
CSSMakeNativeMethod(jni_CSSNodeGetInstanceCount),
|
||||
CSSMakeNativeMethod(jni_CSSLayoutSetLogger),
|
||||
|
|
|
@ -85,6 +85,9 @@ typedef struct CSSStyle {
|
|||
float dimensions[2];
|
||||
float minDimensions[2];
|
||||
float maxDimensions[2];
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
float aspectRatio;
|
||||
} CSSStyle;
|
||||
|
||||
typedef struct CSSNode {
|
||||
|
@ -269,6 +272,8 @@ void CSSNodeInit(const CSSNodeRef node) {
|
|||
node->style.border[edge] = CSSUndefined;
|
||||
}
|
||||
|
||||
node->style.aspectRatio = CSSUndefined;
|
||||
|
||||
node->layout.dimensions[CSSDimensionWidth] = CSSUndefined;
|
||||
node->layout.dimensions[CSSDimensionHeight] = CSSUndefined;
|
||||
|
||||
|
@ -459,6 +464,9 @@ CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimen
|
|||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]);
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
CSS_NODE_STYLE_PROPERTY_IMPL(float, AspectRatio, aspectRatio, aspectRatio);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSEdgeLeft]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSEdgeTop]);
|
||||
CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSEdgeRight]);
|
||||
|
@ -1032,6 +1040,20 @@ static void computeChildFlexBasis(const CSSNodeRef node,
|
|||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (!isMainAxisRow && childWidthMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
return;
|
||||
} else if (isMainAxisRow && childHeightMeasureMode == CSSMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
|
@ -1108,6 +1130,20 @@ static void absoluteLayoutChild(const CSSNodeRef node,
|
|||
}
|
||||
}
|
||||
|
||||
// Exactly one dimension needs to be defined for us to be able to do aspect ratio
|
||||
// calculation. One dimension being the anchor and the other being flexible.
|
||||
if (CSSValueIsUndefined(childWidth) ^ CSSValueIsUndefined(childHeight)) {
|
||||
if (!CSSValueIsUndefined(child->style.aspectRatio)) {
|
||||
if (CSSValueIsUndefined(childWidth)) {
|
||||
childWidth = fmaxf(childHeight * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
|
||||
} else if (CSSValueIsUndefined(childHeight)) {
|
||||
childHeight = fmaxf(childWidth * child->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're still missing one or the other dimension, measure the content.
|
||||
if (CSSValueIsUndefined(childWidth) || CSSValueIsUndefined(childHeight)) {
|
||||
childWidthMeasureMode =
|
||||
|
@ -1774,6 +1810,19 @@ static void layoutNodeImpl(const CSSNodeRef node,
|
|||
}
|
||||
}
|
||||
|
||||
if (!CSSValueIsUndefined(currentRelativeChild->style.aspectRatio)) {
|
||||
if (isMainAxisRow && childHeightMeasureMode != CSSMeasureModeExactly) {
|
||||
childHeight =
|
||||
fmaxf(childWidth * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionColumn));
|
||||
childHeightMeasureMode = CSSMeasureModeExactly;
|
||||
} else if (!isMainAxisRow && childWidthMeasureMode != CSSMeasureModeExactly) {
|
||||
childWidth = fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
|
||||
getPaddingAndBorderAxis(currentRelativeChild, CSSFlexDirectionRow));
|
||||
childWidthMeasureMode = CSSMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionWidth],
|
||||
&childWidthMeasureMode,
|
||||
&childWidth);
|
||||
|
|
|
@ -149,6 +149,15 @@ CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight);
|
|||
CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth);
|
||||
CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
// Aspect ratio control the size of the undefined dimension of a node.
|
||||
// - On a node with a set width/height aspect ratio control the size of the unset dimension
|
||||
// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if unset
|
||||
// - On a node with a measure function aspect ratio works as though the measure function measures the flex basis
|
||||
// - On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis if unset
|
||||
// - Aspect ratio takes min/max dimensions into account
|
||||
CSS_NODE_STYLE_PROPERTY(float, AspectRatio, aspectRatio);
|
||||
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Left);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Top);
|
||||
CSS_NODE_LAYOUT_PROPERTY(float, Right);
|
||||
|
|
Loading…
Reference in New Issue