static void _ZFP_ZFUILinearLayout_layoutVertical(ZF_IN ZFUILinearLayout *parent, ZF_IN const ZFUISize &size, ZF_IN zfbool positiveDirection) { zfint requiredSize = 0; zfint totalWeight = 0; zfbool hasLayoutedChild = zffalse; zfint parentMarginX = ZFUIMarginGetX(parent->layoutChildMargin()); zfint parentMarginY = ZFUIMarginGetY(parent->layoutChildMargin()); for(zfindex i = 0; i < parent->childCount(); ++i) { ZFUIView *child = parent->childAtIndex(i); ZFUILinearLayoutParam *layoutParam = child->layoutParamT(); if(!child->viewVisible() && !layoutParam->layoutReserveSpaceWhenNotVisible()) { continue ; } zfint prevSpace = (hasLayoutedChild ? parent->layoutChildSpace() : 0); hasLayoutedChild = zftrue; zfint marginX = parentMarginX + ZFUIMarginGetX(layoutParam->layoutMargin()); zfint marginY = parentMarginY + ZFUIMarginGetY(layoutParam->layoutMargin()); if(layoutParam->layoutWeight() > 0) { totalWeight += layoutParam->layoutWeight(); } else { switch(layoutParam->sizeParam().height) { case ZFUISizeType::e_Wrap: { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, -marginX)), layoutParam->sizeHint().height), layoutParam->sizeParam()); requiredSize += child->layoutMeasuredSize().height; } break; case ZFUISizeType::e_Fill: requiredSize = size.height; break; default: zfCoreCriticalShouldNotGoHere(); return ; } } requiredSize += prevSpace + marginY; } hasLayoutedChild = zffalse; zfint flexibleSize = zfmMax(0, size.height - requiredSize); zfint offset = (positiveDirection ? 0 : size.height); for(zfindex i = 0; i < parent->childCount(); ++i) { ZFUIView *child = parent->childAtIndex(i); ZFUILinearLayoutParam *layoutParam = child->layoutParamT(); if(!child->viewVisible() && !layoutParam->layoutReserveSpaceWhenNotVisible()) { continue ; } zfint prevSpace = (hasLayoutedChild ? parent->layoutChildSpace() : 0); hasLayoutedChild = zftrue; zfint marginX = parentMarginX + ZFUIMarginGetX(layoutParam->layoutMargin()); zfint marginY = parentMarginY + ZFUIMarginGetY(layoutParam->layoutMargin()); zfint totalUsedSpace = prevSpace + marginY; if(layoutParam->layoutWeight() > 0) { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, -marginX)), ZFUIViewLayoutParam::sizeHintMerge(flexibleSize * layoutParam->layoutWeight() / totalWeight, layoutParam->sizeHint().height) ), ZFUISizeParamMake( layoutParam->sizeParam().width, ZFUISizeType::e_Fill )); flexibleSize -= child->layoutMeasuredSize().height; totalWeight -= layoutParam->layoutWeight(); } else { if(layoutParam->sizeParam().height == ZFUISizeType::e_Fill) { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, -marginX)), ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().height, positiveDirection ? zfmMax(size.height - offset - totalUsedSpace, 0) : zfmMax(offset - totalUsedSpace, 0)) ), layoutParam->sizeParam()); } } if(positiveDirection) { child->layout(ZFUIAlignApply( layoutParam->layoutAlign(), ZFUIRectMake(0, offset + prevSpace, size.width, child->layoutMeasuredSize().height + marginY), child->layoutMeasuredSize(), layoutParam->layoutMargin() + parent->layoutChildMargin())); offset += prevSpace + child->layoutMeasuredSize().height + marginY; } else { offset -= child->layoutMeasuredSize().height + marginY + prevSpace; child->layout(ZFUIAlignApply( layoutParam->layoutAlign(), ZFUIRectMake(0, offset, size.width, child->layoutMeasuredSize().height + marginY), child->layoutMeasuredSize(), layoutParam->layoutMargin() + parent->layoutChildMargin())); } } }
static void _ZFP_ZFUIFlowLayout_layoutVertical(ZF_IN ZFUIFlowLayout *parent, ZF_IN const ZFUISize &size, ZF_IN zfbool positiveDirection) { zfindex wrapIndex = 0; zfint lineSizeUsed = 0; while(wrapIndex < parent->childCount()) // for each line { zfint requiredSize = 0; zfint totalWeight = 0; zfbool hasLayoutedChild = zffalse; zfint parentMarginX = ZFUIMarginGetX(parent->layoutChildMargin()); zfint parentMarginY = ZFUIMarginGetY(parent->layoutChildMargin()); zfindex wrapIndexTmp = parent->childCount(); zfint lineSize = 0; zfint prevLineSpace = (wrapIndex > 0 ? parent->layoutChildSpaceX() : 0); zfint flexableWrapSize = 0; for(zfindex i = wrapIndex; i < parent->childCount(); ++i) { ZFUIView *child = parent->childAtIndex(i); ZFUIFlowLayoutParam *layoutParam = child->layoutParamT(); if(!child->viewVisible() && !layoutParam->layoutReserveSpaceWhenNotVisible()) { continue ; } zfint prevSpace = (hasLayoutedChild ? parent->layoutChildSpaceY() : 0); hasLayoutedChild = zftrue; zfint marginX = parentMarginX + ZFUIMarginGetX(layoutParam->layoutMargin()); zfint marginY = parentMarginY + ZFUIMarginGetY(layoutParam->layoutMargin()); zfint childRequiredSize = 0; if(layoutParam->layoutWeight() > 0) { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, 0 - lineSizeUsed - marginX - prevLineSpace)), layoutParam->sizeHint().height), layoutParam->sizeParam()); childRequiredSize += child->layoutMeasuredSize().height; } else { switch(layoutParam->sizeParam().height) { case ZFUISizeType::e_Wrap: child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, 0 - lineSizeUsed - marginX - prevLineSpace)), layoutParam->sizeHint().height), layoutParam->sizeParam()); childRequiredSize += child->layoutMeasuredSize().height; break; case ZFUISizeType::e_Fill: child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, 0 - lineSizeUsed - marginX - prevLineSpace)), layoutParam->sizeHint().height), layoutParam->sizeParam()); childRequiredSize = zfmMax( child->layoutMeasuredSize().height, size.height - requiredSize - prevSpace - marginY); break; default: zfCoreCriticalShouldNotGoHere(); return ; } } childRequiredSize += prevSpace + marginY; if(i > wrapIndex && requiredSize + childRequiredSize > size.height) { wrapIndexTmp = i; break; } if(layoutParam->layoutWeight() > 0) { flexableWrapSize += childRequiredSize; } requiredSize += childRequiredSize; lineSize = zfmMax(lineSize, child->layoutMeasuredSize().width + marginX); if(layoutParam->layoutWeight() > 0) { totalWeight += layoutParam->layoutWeight(); } if(requiredSize >= size.height) { wrapIndexTmp = i + 1; break; } } hasLayoutedChild = zffalse; zfint flexibleSize = zfmMax(0, size.height - requiredSize + flexableWrapSize); zfint offset = (positiveDirection ? 0 : size.height); zfint lineX = ((_ZFP_ZFUIFlowLayout_layoutOrientationSecondary( parent->layoutOrientationMain(), parent->layoutOrientationSecondary()) == ZFUIOrientation::e_Left) ? lineSizeUsed + prevLineSpace : size.width - lineSizeUsed - lineSize - prevLineSpace); for(zfindex i = wrapIndex; i < wrapIndexTmp; ++i) { ZFUIView *child = parent->childAtIndex(i); ZFUIFlowLayoutParam *layoutParam = child->layoutParamT(); if(!child->viewVisible() && !layoutParam->layoutReserveSpaceWhenNotVisible()) { continue ; } zfint prevSpace = (hasLayoutedChild ? parent->layoutChildSpaceY() : 0); hasLayoutedChild = zftrue; zfint marginX = parentMarginX + ZFUIMarginGetX(layoutParam->layoutMargin()); zfint marginY = parentMarginY + ZFUIMarginGetY(layoutParam->layoutMargin()); zfint totalUsedSpace = prevSpace + marginY; if(layoutParam->layoutWeight() > 0) { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, 0 - lineSizeUsed - marginX - prevLineSpace)), ZFUIViewLayoutParam::sizeHintMerge(flexibleSize * layoutParam->layoutWeight() / totalWeight, layoutParam->sizeHint().height) ), ZFUISizeParamMake( layoutParam->sizeParam().width, ZFUISizeType::e_Fill )); flexibleSize -= child->layoutMeasuredSize().height; totalWeight -= layoutParam->layoutWeight(); } else { if(layoutParam->sizeParam().height == ZFUISizeType::e_Fill) { child->layoutMeasure( ZFUISizeMake( ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().width, ZFUIViewLayoutParam::sizeHintOffset(size.width, 0 - lineSizeUsed - marginX - prevLineSpace)), ZFUIViewLayoutParam::sizeHintMerge( layoutParam->sizeHint().height, positiveDirection ? zfmMax(size.height - offset - totalUsedSpace, 0) : zfmMax(offset - totalUsedSpace, 0)) ), layoutParam->sizeParam()); } } if(positiveDirection) { child->layout(ZFUIAlignApply( layoutParam->layoutAlign(), ZFUIRectMake(lineX, offset + prevSpace, lineSize, child->layoutMeasuredSize().height + marginY), child->layoutMeasuredSize(), layoutParam->layoutMargin() + parent->layoutChildMargin())); offset += prevSpace + child->layoutMeasuredSize().height + marginY; } else { offset -= child->layoutMeasuredSize().height + marginY + prevSpace; child->layout(ZFUIAlignApply( layoutParam->layoutAlign(), ZFUIRectMake(lineX, offset, lineSize, child->layoutMeasuredSize().height + marginY), child->layoutMeasuredSize(), layoutParam->layoutMargin() + parent->layoutChildMargin())); } } // for(zfindex i = wrapIndex; i < wrapIndexTmp; ++i) wrapIndex = wrapIndexTmp; lineSizeUsed += lineSize + prevLineSpace; } // for each line }