/*
Yoga 是一个针对 Web 标准的嵌入式布局引擎。
https://www.yogalayout.dev/docs/styling/
https://www.yogalayout.dev/playground
其它类似:
https://github.com/Tencent/Taitank
*/
#include <yoga/Yoga.h>
void applyLayout(YGNodeRef node) {
//if (!YGNodeHasNewLayout(node)) {
// return;
//}
if (!YGNodeIsDirty(node))
return;
// Reset the flag
YGNodeSetHasNewLayout(node, false);
// Do the real work
for (size_t i = 0; i < YGNodeGetChildCount(node); i++) {
applyLayout(YGNodeGetChild(node, i));
}
}
static float _baselineFunc(
YGNodeConstRef /*node*/,
const float /*width*/,
const float height) {
return height / 2;
}
static float
_baseline(YGNodeConstRef node, const float /*width*/, const float /*height*/) {
auto* baseline = (float*)YGNodeGetContext(node);
return *baseline;
}
static YGSize _measure1(
YGNodeConstRef /*node*/,
float /*width*/,
YGMeasureMode /*widthMode*/,
float /*height*/,
YGMeasureMode /*heightMode*/) {
return YGSize{ 42, 50 };
}
static void _dirtied(YGNodeConstRef node) {
int* dirtiedCount = (int*)YGNodeGetContext(node);
(*dirtiedCount)++;
}
void test() {
// 设置
YGConfigRef config = YGConfigNew();
YGConfigSetUseWebDefaults(config, true);
// Setup config...
YGConfigSetErrata(config, YGErrataClassic); // None,Classic,All
YGConfigSetPointScaleFactor(config, 2.0f); // 网格对齐,0禁用
YGNodeRef root = YGNodeNewWithConfig(config);
//YGNodeRef root = YGNodeNew();
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetOverflow(root, YGOverflowHidden);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetJustifyContent(root, YGJustifyCenter);
YGNodeStyleSetAlignItems(root, YGAlignCenter);
YGNodeStyleSetAlignContent(root, YGAlignCenter);
YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse);
YGNodeStyleSetFlexGrow(root, 1);
YGNodeStyleSetFlexShrink(root, 1);
YGNodeStyleSetFlexBasisPercent(root, 0);
YGNodeStyleSetMargin(root, YGEdgeLeft, 10);
YGNodeStyleSetPadding(root, YGEdgeTop, 10);
YGNodeStyleSetPaddingPercent(root, YGEdgeLeft, 3);
YGNodeStyleSetBorder(root, YGEdgeBottom, 10);
YGNodeStyleSetGap(root, YGGutterRow, 10);
//YGNodeStyleSetGapPercent(root, YGGutterRow, 10);
YGNodeStyleSetWidth(root, 100.0f);
YGNodeStyleSetHeight(root, 100.0f);
YGNodeStyleSetMaxHeight(root, 500);
YGNodeStyleSetMinHeight(root, 500);
YGNodeStyleSetMinWidthPercent(root, 10);
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeRef child0 = YGNodeNew();
YGNodeStyleSetPosition(child0, YGEdgeTop, 10);
YGNodeStyleSetAlignSelf(child0, YGAlignCenter);
YGNodeStyleSetPositionPercent(child0, YGEdgeTop, 50);
YGNodeStyleSetWidthPercent(child0, 20);
YGNodeStyleSetAspectRatio(child0, 1 / 1); // 宽高比
YGNodeStyleSetFlexGrow(child0, 1.0f);
YGNodeStyleSetFlexBasis(child0, 50);
YGNodeStyleSetMargin(child0, YGEdgeRight, 10.0f);
YGNodeStyleSetDisplay(child0, YGDisplayNone);
YGNodeStyleSetMarginAuto(child0, YGEdgeRight);
YGNodeInsertChild(root, child0, 0.0f);
float baselineValue = 10;
YGNodeRef child1 = YGNodeNew();
YGNodeCopyStyle(child0, child1);
YGNodeSetContext(child1, &baselineValue);
YGNodeStyleSetFlexGrow(child1, 1.0f);
YGNodeSetIsReferenceBaseline(child1, true);
YGNodeSetBaselineFunc(child1, _baselineFunc);
YGNodeSetBaselineFunc(child1, _baseline);
YGNodeSetMeasureFunc(child1, _measure1);
int dirtiedCount = 0;
YGNodeSetContext(root, &dirtiedCount);
YGNodeSetDirtiedFunc(root, _dirtied);
YGNodeInsertChild(root, child1, 1.0f);
// 层级单独创建
YGNodeRef const root_child0 = YGNodeNew();
YGNodeRef const root_child1 = YGNodeNew();
YGNodeRef children[] = { root_child0, root_child1 };
YGNodeSetChildren(root, children, 2);
root = YGNodeGetOwner(root_child0);
// 布局
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
// 获取 margin, border, and padding
float left = YGNodeLayoutGetLeft(child0);
float height = YGNodeLayoutGetHeight(child0);
// 设置测量函数 MeasureMode Exactly(stretch-fit) Undefined(max-content) AtMost(fit-content)
// 通过测量函数委托给不同的布局系统,比如文本排版
//Widget widget{};
//YGNodeSetContext(node, &w);
//YGNodeSetMeasureFunc(node, &measureWidget);
// 添加脏区
//YGNodeMarkDirty(child1);
// 设置行flex行间距
// YGNodeStyleSetGap(node, YGGutterRow, amount);
// 设置布局后偏移
// YGNodeStyleSetPosition(node, edge, position);
// ceil/floor flags
//ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.01, 2.0, false, false));
//YGNodeFree(child0);
//YGNodeFree(child1);
//YGNodeRemoveAllChildren(root);
YGNodeFreeRecursive(root);
YGConfigFree(config);
}