123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- #ifdef __cplusplus
- #ifndef WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H
- #define WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H
- #include <string.h>
- #include <math.h>
- #include <vector>
- #include <iostream>
- #include <string>
- #include <algorithm>
- #include "style.h"
- #include "flex_enum.h"
- namespace WeexCore {
- class WXCoreLayoutNode;
- class WXCoreFlexLine;
- enum FormattingContext {
- kBFC,
- kNonBFC,
- } ;
- enum MeasureMode {
- kUnspecified = 0,
- kExactly,
- } ;
- struct WXCoreSize {
- private:
- float hypotheticalWidth;
- float hypotheticalHeight;
- public:
- friend class WXCoreLayoutNode;
- float width;
- float height;
- WXCoreSize() : hypotheticalWidth(NAN),
- hypotheticalHeight(NAN),
- width(0), height(0) {}
- inline void reset() {
- hypotheticalWidth = NAN ;
- hypotheticalHeight = NAN;
- width = 0;
- height = 0;
- }
- inline bool isNAN() {
- return isnan(width) || isnan(height);
- }
- };
- /**
- * layout-result:layout-height、layout-width、position(left、right、top、bottom)、direction
- */
- struct WXCorelayoutResult {
- WXCoreDirection mLayoutDirection;
- WXCoreSize mLayoutSize;
- WXCorePosition mLayoutPosition;
- inline bool isNAN() {
- return mLayoutSize.isNAN() || mLayoutPosition.isNAN();
- }
- inline void reset() {
- mLayoutSize.reset();
- mLayoutPosition.reset();
- mLayoutDirection = kDirectionInherit;
- }
- };
- typedef WXCoreSize(*WXCoreMeasureFunc)(WXCoreLayoutNode *node, float width,
- MeasureMode widthMeasureMode,
- float height, MeasureMode heightMeasureMode);
- using Index = std::vector<WXCoreLayoutNode *>::size_type;
- /**
- * flie line
- */
- class WXCoreFlexLine {
- public:
- float mMainSize;
- float mCrossSize;
- Index mItemCount;
- float mTotalFlexGrow;
- float mTotalFlexibleSize;
- /**
- * Store the indices of the children views whose mAlignSelf property is stretch.
- * The stored indices are the absolute indices including all children in the Flexbox,
- * not the relative indices in this flex line.
- */
- std::vector<Index> mIndicesAlignSelfStretch;
- WXCoreFlexLine() : mMainSize(0),
- mCrossSize(0),
- mItemCount(0),
- mTotalFlexGrow(0),
- mTotalFlexibleSize(0) {
- }
- ~WXCoreFlexLine() {
- mMainSize = 0;
- mCrossSize = 0;
- mItemCount = 0;
- mTotalFlexGrow = 0;
- mTotalFlexibleSize = 0;
- mIndicesAlignSelfStretch.clear();
- }
- };
- /**
- * Layout node
- */
- class WXCoreLayoutNode {
- public:
- WXCoreLayoutNode() :
- mParent(nullptr),
- dirty(true),
- widthDirty{false},
- heightDirty{false},
- mHasNewLayout(true),
- mIsDestroy(false),
- measureFunc(nullptr) {
- mCssStyle = new WXCoreCSSStyle();
- mLayoutResult = new WXCorelayoutResult();
- }
- virtual ~WXCoreLayoutNode() {
- mIsDestroy = true;
- mHasNewLayout = true;
- dirty = true;
- measureFunc = nullptr;
- mParent = nullptr;
- mChildList.clear();
- BFCs.clear();
- NonBFCs.clear();
- mChildrenFrozen.clear();
- for (WXCoreFlexLine *flexLine : mFlexLines) {
- if (flexLine != nullptr) {
- delete flexLine;
- flexLine = nullptr;
- }
- }
- mFlexLines.clear();
- if (mCssStyle != nullptr) {
- delete mCssStyle;
- mCssStyle = nullptr;
- }
- if (mLayoutResult != nullptr) {
- delete mLayoutResult;
- mLayoutResult = nullptr;
- }
- }
- private:
- /**
- * Holds the 'frozen' state of children during measure. If a view is frozen it will no longer
- * expand regardless of mFlexGrow. Items are indexed by the child's
- * reordered index.
- */
- std::vector<bool> mChildrenFrozen;
- std::vector<WXCoreFlexLine *> mFlexLines;
- std::vector<WXCoreLayoutNode *> mChildList;
- std::vector<WXCoreLayoutNode *> BFCs;
- std::vector<WXCoreLayoutNode *> NonBFCs;
- WXCoreLayoutNode *mParent = nullptr;
- WXCoreCSSStyle *mCssStyle = nullptr;
- MeasureMode widthMeasureMode = kUnspecified;
- MeasureMode heightMeasureMode = kUnspecified;
- WXCorelayoutResult *mLayoutResult = nullptr;
- WXCorePosition *absoultePositon = nullptr;
- bool mHasNewLayout;
- bool dirty, widthDirty, heightDirty;
- bool mIsDestroy = true;
-
- bool mNeedsPlatformDependentLayout = false;
- WXCoreMeasureFunc measureFunc = nullptr;
- void *context = nullptr;
- /** ================================ Cache:Last calculate result =================================== **/
- public:
- /** ================================ Engine Entry Function =================================== **/
- void calculateLayout(const std::pair<float,float>&);
- /** ================================ measureFunc =================================== **/
- inline void setMeasureFunc(WXCoreMeasureFunc measure) {
- measureFunc = measure;
- markDirty();
- }
- inline bool haveMeasureFunc() const {
- return nullptr != measureFunc;
- }
- inline WXCoreMeasureFunc getMeasureFunc() const {
- return measureFunc;
- }
- /** ================================ context =================================== **/
- inline void *getContext() const {
- return context;
- }
- inline void setContext(void * const context) {
- this->context = context;
- }
-
- inline void copyStyle(WXCoreLayoutNode *srcNode) {
- if (srcNode != nullptr && memcmp(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle)) != 0) {
- memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle));
- markDirty();
- }
- }
-
- void copyFrom(WXCoreLayoutNode* srcNode){
- if (srcNode == nullptr) return;
-
- memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle));
- }
- inline void copyMeasureFunc(WXCoreLayoutNode *srcNode) {
- if (srcNode != nullptr && memcmp(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)) != 0) {
- memcpy(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc));
- markDirty();
- }
- }
-
- /** ================================ custom =================================== **/
- inline bool getNeedsPlatformDependentLayout() const {
- return mNeedsPlatformDependentLayout;
- }
-
- inline void setNeedsPlatformDependentLayout(bool v) {
- this->mNeedsPlatformDependentLayout = v;
- }
-
- private:
- /** ================================ measure =================================== **/
- inline void reset() {
- if (isDirty()) {
- mLayoutResult->reset();
- for (WXCoreFlexLine *flexLine : mFlexLines) {
- if (flexLine != nullptr) {
- delete flexLine;
- flexLine = nullptr;
- }
- }
- mFlexLines.clear();
- mChildrenFrozen.assign(getChildCount(kNonBFC), false);
- }
- widthMeasureMode = isnan(mCssStyle->mStyleWidth) ? kUnspecified : kExactly;
- heightMeasureMode = isnan(mCssStyle->mStyleHeight) ? kUnspecified : kExactly;
- }
- inline void setLayoutWidth(const float width) {
- if (mLayoutResult->mLayoutSize.width != width &&
- (!isnan(width) || !isnan(mLayoutResult->mLayoutSize.width))) {
- mLayoutResult->mLayoutSize.width = width;
- widthDirty = true;
- markDirty(false);
- }
- }
- inline void setLayoutHeight(const float height) {
- if (mLayoutResult->mLayoutSize.height != height &&
- (!isnan(height) || !isnan(mLayoutResult->mLayoutSize.height))) {
- mLayoutResult->mLayoutSize.height = height;
- heightDirty = true;
- markDirty(false);
- }
- }
- inline void setWidthMeasureMode(const MeasureMode measureMode) {
- if (widthMeasureMode != measureMode) {
- widthMeasureMode = measureMode;
- if (getChildCount(kNonBFC) > 0) {
- widthDirty = true;
- }
- }
- }
- inline void setHeightMeasureMode(const MeasureMode measureMode) {
- if (heightMeasureMode != measureMode) {
- heightMeasureMode = measureMode;
- if (getChildCount(kNonBFC) > 0) {
- heightDirty = true;
- }
- }
- }
- inline float firstLineCrossSize() const {
- float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this));
- if (!mFlexLines.empty()) {
- sum += mFlexLines[0]->mCrossSize;
- }
- return sum;
- }
- inline float getSumOfCrossSize() const {
- float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this));
- for (WXCoreFlexLine *flexLine: mFlexLines) {
- sum += flexLine->mCrossSize;
- }
- return sum;
- }
- inline bool isMainAxisHorizontal(const WXCoreLayoutNode* const node) const {
- return node->mCssStyle->mFlexDirection == kFlexDirectionRow ||
- node->mCssStyle->mFlexDirection == kFlexDirectionRowReverse;
- }
- inline bool isCrossExactly() const {
- return isMainAxisHorizontal(this) ? heightMeasureMode == kExactly
- : widthMeasureMode == kExactly;
- }
- inline float sumPaddingBorderAlongAxis(const WXCoreLayoutNode* const node, bool horizontal) const {
- float paddingBorderAlongAxis;
- if (horizontal) {
- paddingBorderAlongAxis =
- node->mCssStyle->mPadding.getPadding(kPaddingLeft) +
- node->mCssStyle->mPadding.getPadding(kPaddingRight) +
- node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft) +
- node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight);
- } else {
- paddingBorderAlongAxis =
- node->mCssStyle->mPadding.getPadding(kPaddingTop) +
- node->mCssStyle->mPadding.getPadding(kPaddingBottom) +
- node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop) +
- node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom);
- }
- return paddingBorderAlongAxis;
- }
- inline bool isWrapRequired(const float &width, const float &height,
- const float ¤tLength, const float &childLength) const {
- float freeMainSize = CalculateFreeSpaceAlongMainAxis(width, height, currentLength);
- return !isSingleFlexLine(freeMainSize) && freeMainSize < childLength;
- }
- //If width/height is NAN, ret is NAN, which property we use on purpose.
- virtual float CalculateFreeSpaceAlongMainAxis(const float &width, const float &height,
- const float ¤tLength) const{
- float ret;
- if(isMainAxisHorizontal(this)){
- ret = width - sumPaddingBorderAlongAxis(this, true) - currentLength;
- }
- else{
- ret = height - sumPaddingBorderAlongAxis(this, false) - currentLength;
- }
- return ret;
- }
- inline bool isSingleFlexLine(const float &mainSize) const {
- return mCssStyle->mFlexWrap == kNoWrap || isnan(mainSize);
- }
- inline void sumFlexGrow(const WXCoreLayoutNode* const child, WXCoreFlexLine* const flexLine, Index i){
- if (child->mCssStyle->mFlexGrow > 0) {
- flexLine->mTotalFlexGrow += child->mCssStyle->mFlexGrow;
- mChildrenFrozen[i] = false;
- if (isMainAxisHorizontal(this)) {
- if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalWidth)) {
- flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalWidth;
- }
- } else {
- if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalHeight)) {
- flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalHeight;
- }
- }
- } else {
- mChildrenFrozen[i] = true;
- }
- }
- inline void setMeasuredDimensionForFlex(
- const float width, const MeasureMode widthMeasureMode,
- const float height, const MeasureMode heightMeasureMode){
- float actualWidth, actualHeight;
- if (isMainAxisHorizontal(this)) {
- actualWidth = widthMeasureMode == kExactly ? width : getLargestMainSize();
- actualHeight = heightMeasureMode == kExactly ? height : getSumOfCrossSize();
- } else {
- actualHeight = heightMeasureMode == kExactly ? height : getLargestMainSize();
- actualWidth = widthMeasureMode == kExactly ? width : firstLineCrossSize();
- }
- setMeasuredDimension(actualWidth, actualHeight);
- }
- inline float calcItemSizeAlongAxis(const WXCoreLayoutNode* const node, const bool horizontal, const bool useHypotheticalSize = false) const {
- float ret;
- if (horizontal) {
- ret = node->mCssStyle->mMargin.getMargin(kMarginLeft) +
- node->mCssStyle->mMargin.getMargin(kMarginRight);
- ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalWidth
- : node->mLayoutResult->mLayoutSize.width;
- } else {
- ret = node->mCssStyle->mMargin.getMargin(kMarginTop) +
- node->mCssStyle->mMargin.getMargin(kMarginBottom);
- ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalHeight
- : node->mLayoutResult->mLayoutSize.height;
- }
- return ret;
- }
- inline void limitMainSizeForFlexGrow(WXCoreFlexLine* const flexLine, const Index childIndex,
- const float flexGrow) {
- mChildrenFrozen[childIndex] = true;
- flexLine->mTotalFlexGrow -= flexGrow;
- }
- inline void setMeasuredDimension(const float width, const float height) {
- mLayoutResult->mLayoutSize.width = width;
- mLayoutResult->mLayoutSize.height = height;
- }
- inline std::pair<bool, float> limitChildMainSize(WXCoreFlexLine* const flexLine, const WXCoreLayoutNode* const child,
- float childSizeAlongMainAxis, const Index childIndex){
- bool needsReexpand = false;
- if (isMainAxisHorizontal(this)) {
- if (!isnan(child->mCssStyle->mMaxWidth) &&
- childSizeAlongMainAxis > child->mCssStyle->mMaxWidth) {
- needsReexpand = true;
- childSizeAlongMainAxis = child->mCssStyle->mMaxWidth;
- } else if (!isnan(child->mCssStyle->mMinWidth) &&
- childSizeAlongMainAxis < child->mCssStyle->mMinWidth) {
- needsReexpand = true;
- childSizeAlongMainAxis = child->mCssStyle->mMinWidth;
- }
- } else {
- if (!isnan(child->mCssStyle->mMaxHeight) &&
- childSizeAlongMainAxis > child->mCssStyle->mMaxHeight) {
- needsReexpand = true;
- childSizeAlongMainAxis = child->mCssStyle->mMaxHeight;
- } else if (!isnan(child->mCssStyle->mMinHeight) &&
- childSizeAlongMainAxis < child->mCssStyle->mMinHeight) {
- needsReexpand = true;
- childSizeAlongMainAxis = child->mCssStyle->mMinHeight;
- }
- }
- limitMainSizeForFlexGrow(flexLine, childIndex, child->mCssStyle->mFlexGrow);
- return std::make_pair(needsReexpand, childSizeAlongMainAxis);
- }
- void updateLeftRightForAbsolute(float &left, float &right,
- const WXCorePadding &parentPadding,
- const WXCoreBorderWidth &parentBorder,
- const WXCoreSize &parentSize) const {
- if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft))) {
- if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeRight))) {
- ;
- } else {
- right += parentSize.width -
- (parentBorder.getBorderWidth(kBorderWidthRight) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeRight)
- + mLayoutResult->mLayoutSize.width);
- left += parentSize.width -
- (parentBorder.getBorderWidth(kBorderWidthRight) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeRight)
- + mLayoutResult->mLayoutSize.width);
- }
- } else {
- left += parentBorder.getBorderWidth(kBorderWidthLeft) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
- right += parentBorder.getBorderWidth(kBorderWidthLeft) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
- }
- }
- void updateTopBottomForAbsolute(float &top, float &bottom,
- const WXCorePadding &parentPadding,
- const WXCoreBorderWidth &parentBorder,
- const WXCoreSize &parentSize) const {
- if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeTop))) {
- if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom))) {
- ;
- } else {
- top += parentSize.height -
- (parentBorder.getBorderWidth(kBorderWidthBottom) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom)
- + mLayoutResult->mLayoutSize.height);
- bottom += parentSize.height -
- (parentBorder.getBorderWidth(kBorderWidthBottom) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom)
- + mLayoutResult->mLayoutSize.height);
- }
- } else {
- top += parentBorder.getBorderWidth(kBorderWidthTop) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
- bottom += parentBorder.getBorderWidth(kBorderWidthTop) +
- mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
- }
- }
- /** ================================ other =================================== **/
- inline void clearDirty() {
- dirty = false;
- widthDirty = false;
- heightDirty = false;
- }
- void
- measure(float, float, bool);
- void hypotheticalMeasure(float, float, bool = false);
- void measureLeafNode(float, float, bool, bool);
- void measureInternalNode(float, float, bool, bool);
- void updateCurrentFlexline(Index, WXCoreFlexLine *, Index, const WXCoreLayoutNode *, bool);
- void measureChild(WXCoreLayoutNode* , float, float, float, bool, bool);
- void adjustChildSize(WXCoreLayoutNode *, float);
- void adjustChildSize(const WXCoreLayoutNode *child,
- const float currentMainSize,
- const float parentWidth,
- const float parentHeight,
- float &childWidth,
- float &childHeight) const;
- void stretchViewCrossSize();
- void stretchViewCrossSize(WXCoreLayoutNode *, float);
- Index expandItemsInFlexLine(WXCoreFlexLine *, float, Index);
- void checkSizeConstraints(WXCoreLayoutNode *, bool);
- void
- determineMainSize(float width, float height);
- void
- determineCrossSize(float, float, bool);
- void
- determineCrossSize(float, float, WXCoreFlexLine *);
- void setFrame(float, float, float, float);
- void setFrame(WXCorePosition*,float, float, float, float);
- /** ================================ layout =================================== **/
- void layout(float left, float top, float right, float bottom, bool, const std::pair<float,float>* = nullptr);
- void calcRelativeOffset(float &left, float &top, float &right, float &bottom) const ;
- void calcAbsoluteOffset(float &left, float &top, float &right, float &bottom, const std::pair<float,float>* = nullptr);
- void positionAbsoluteFlexItem(float &left, float &top, float &right, float &bottom);
- void layoutHorizontal(bool isRtl, float left, float top, float right, float bottom,
- WXCoreLayoutNode*, WXCoreFlexLine *const flexLine);
- void layoutFlexlineHorizontal(const float width,
- const WXCoreFlexLine *const flexLine,
- float &childLeft,
- float &childRight,
- float &spaceBetweenItem) const;
- void layoutSingleChildHorizontal(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine,
- WXCoreFlexWrap flexWrap, WXCoreAlignItems alignItems,
- float, float, float, float, bool);
- void layoutSingleChildHorizontal(const bool isRtl,
- const bool,
- float childBottom, float childTop,
- WXCoreFlexLine *const flexLine,
- WXCoreLayoutNode *const child,
- float&, float&);
- void layoutVertical(bool isRtl, bool fromBottomToTop, float left, float top, float right, float bottom,
- WXCoreLayoutNode*, WXCoreFlexLine *const flexLine);
- void layoutFlexlineVertical(const float height,
- const WXCoreFlexLine *const flexLine,
- float &childTop,
- float &childBottom,
- float &spaceBetweenItem) const;
- void layoutSingleChildVertical(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine,
- bool isRtl, WXCoreAlignItems alignItems,
- float, float, float, float, bool);
- void layoutSingleChildVertical(const bool isRtl, const bool fromBottomToTop,
- const bool absoluteFlexItem,
- const float childLeft, const float childRight,
- WXCoreFlexLine *const flexLine,
- WXCoreLayoutNode *const child,
- float& ,float&);
- void updateFlexLineForAbsoluteItem(WXCoreLayoutNode *const absoluteFlexItem, WXCoreFlexLine *const flexLine);
- void initFormatingContext(std::vector<WXCoreLayoutNode *> &BFCs);
- std::pair<bool,float> calculateBFCWidth(float, float);
- std::pair<bool,float> calculateBFCHeight(float, float);
- std::tuple<bool, float, float> calculateBFCDimension(const std::pair<float,float>&);
- virtual void OnLayoutBefore() {
- }
- virtual void OnLayoutAfter(float width, float height) {
- }
- public:
- virtual void onLayout(float left, float top, float right, float bottom, WXCoreLayoutNode* = nullptr, WXCoreFlexLine *const flexLine = nullptr);
- /** ================================ tree =================================== **/
- inline Index getChildCount(FormattingContext formattingContext) const {
- switch (formattingContext) {
- case kNonBFC:
- return NonBFCs.size();
- case kBFC:
- return BFCs.size();
- default:
- return mChildList.size();
- }
- }
- inline Index getChildCount() const {
- return mChildList.size();
- }
- inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterBegin() {
- return mChildList.cbegin();
- }
- inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterEnd() {
- return mChildList.cend();
- }
- inline bool hasChild(const WXCoreLayoutNode* const child){
- if(std::find(mChildList.begin(), mChildList.end(), child) != mChildList.end()){
- return true;
- }else{
- return false;
- }
- }
- inline void removeChild(const WXCoreLayoutNode* const child) {
- for (int index = 0; index < mChildList.size(); index++) {
- if (child == mChildList[index]) {
- mChildList.erase(mChildList.begin() + index);
- break;
- }
- }
- markDirty();
- }
- inline void addChildAt(WXCoreLayoutNode* const child, Index index) {
- mChildList.insert(mChildList.begin() + index, child);
- child->mParent = this;
- markDirty();
- }
- inline WXCoreLayoutNode *getChildAt(const FormattingContext formattingContext, const Index index) const {
- switch (formattingContext) {
- case kNonBFC:
- return NonBFCs[index];
- case kBFC:
- return BFCs[index];
- default:
- return mChildList[index];
- }
- }
- inline WXCoreLayoutNode *getChildAt(const Index index) const {
- return mChildList[index];
- }
- inline WXCoreLayoutNode *getParent() const {
- return mParent;
- }
- inline void setParent(WXCoreLayoutNode * const parent, WXCoreLayoutNode * const child) const {
- child->mParent = parent;
- }
- inline bool isBFC(WXCoreLayoutNode* const node) const {
- return node->mCssStyle->mPositionType == kAbsolute || node->mCssStyle->mPositionType == kFixed;
- }
- /** ================================ margin =================================== **/
- inline float getMarginTop() const {
- return mCssStyle->mMargin.getMargin(kMarginTop);
- }
- inline float getMarginBottom() const {
- return mCssStyle->mMargin.getMargin(kMarginBottom);
- }
- inline float getMarginLeft() const {
- return mCssStyle->mMargin.getMargin(kMarginLeft);
- }
- inline float getMarginRight() const {
- return mCssStyle->mMargin.getMargin(kMarginRight);
- }
- inline void setMargin(const WXCoreMarginEdge &edge, const float margin) {
- if (mCssStyle->mMargin.setMargin(edge, margin)) {
- markDirty();
- }
- }
- inline const WXCoreMargin &GetMargins() const {
- return mCssStyle->mMargin;
- }
- /** ================================ padding =================================== **/
- inline float getPaddingLeft() const {
- return mCssStyle->mPadding.getPadding(kPaddingLeft);
- }
- inline float getPaddingRight() const {
- return mCssStyle->mPadding.getPadding(kPaddingRight);
- }
- inline float getPaddingTop() const {
- return mCssStyle->mPadding.getPadding(kPaddingTop);
- }
- inline float getPaddingBottom() const {
- return mCssStyle->mPadding.getPadding(kPaddingBottom);
- }
- inline void setPadding(const WXCorePaddingEdge edge, const float padding) {
- if (mCssStyle->mPadding.setPadding(edge, padding)) {
- markDirty();
- }
- }
- inline const WXCorePadding &GetPaddings() const {
- return mCssStyle->mPadding;
- }
- /** ================================ border-width =================================== **/
- inline float getBorderWidthLeft() const {
- return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft);
- }
- inline float getBorderWidthRight() const {
- return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight);
- }
- inline float getBorderWidthTop() const {
- return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop);
- }
- inline float getBorderWidthBottom() const {
- return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom);
- }
- inline void setBorderWidth(const WXCoreBorderWidthEdge edge, const float borderWidth) {
- if (mCssStyle->mBorderWidth.setBorderWidth(edge, borderWidth)) {
- markDirty();
- }
- }
- inline const WXCoreBorderWidth &GetBorders() const {
- return mCssStyle->mBorderWidth;
- }
- /** ================================ position-type =================================== **/
- inline void setStylePositionType(const WXCorePositionType positionType) {
- if (mCssStyle->mPositionType != positionType) {
- mCssStyle->mPositionType = positionType;
- markDirty();
- }
- }
- inline WXCorePositionType getStylePositionType() const {
- return mCssStyle->mPositionType;
- }
- /** ================================ position =================================== **/
- inline float getStylePositionTop() const {
- return mCssStyle->mStylePosition.getPosition(kPositionEdgeTop);
- }
- inline float getStylePositionBottom() const {
- return mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom);
- }
- inline float getStylePositionLeft() const {
- return mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft);
- }
- inline float getStylePositionRight() const {
- return mCssStyle->mStylePosition.getPosition(kPositionEdgeRight);
- }
- inline void setStylePosition(const WXCorePositionEdge edge, const float positionRight) {
- if (mCssStyle->mStylePosition.setPosition(edge, positionRight))
- markDirty();
- }
- /** ================================ dimension =================================== **/
- inline void setStyleWidthLevel(const DimensionLevel level) const {
- if (mCssStyle->mStyleWidthLevel != level) {
- mCssStyle->mStyleWidthLevel = level;
- }
- }
- inline void setStyleHeightLevel(const DimensionLevel level) const {
- if (mCssStyle->mStyleHeightLevel != level) {
- mCssStyle->mStyleHeightLevel = level;
- }
- }
- inline DimensionLevel getStyleHeightLevel() const {
- return mCssStyle->mStyleHeightLevel;
- }
- inline DimensionLevel getStyleWidthLevel() const {
- return mCssStyle->mStyleWidthLevel;
- }
- inline void setStyleWidth(const float width, const bool updating) {
- if (mCssStyle->mStyleWidth != width) {
- mCssStyle->mStyleWidth = width;
- markDirty();
- if(updating) {
- markChildrenDirty(true);
- }
- }
- }
- inline void setStyleWidthToNAN() {
- if (!isnan(mCssStyle->mStyleWidth)) {
- mCssStyle->mStyleWidth = NAN;
- markDirty();
- markChildrenDirty(true);
- }
- }
- inline float getStyleWidth() const {
- return mCssStyle->mStyleWidth;
- }
- inline void setStyleHeight(const float height) {
- if (mCssStyle->mStyleHeight != height) {
- mCssStyle->mStyleHeight = height;
- markDirty();
- }
- }
- inline float getStyleHeight() const {
- return mCssStyle->mStyleHeight;
- }
- inline void setMinWidth(const float minWidth, const bool updating) {
- if (mCssStyle->mMinWidth != minWidth) {
- mCssStyle->mMinWidth = minWidth;
- markDirty();
- if(updating) {
- markChildrenDirty(true);
- }
- }
- }
- inline float getMinWidth() const {
- return mCssStyle->mMinWidth;
- }
- inline void setMaxWidth(const float maxWidth, const bool updating) {
- if (mCssStyle->mMaxWidth != maxWidth) {
- mCssStyle->mMaxWidth = maxWidth;
- markDirty();
- if(updating) {
- markChildrenDirty(true);
- }
- }
- }
- inline float getMaxWidth() const {
- return mCssStyle->mMaxWidth;
- }
- inline void setMinHeight(const float minHeight) {
- if (mCssStyle->mMinHeight != minHeight) {
- mCssStyle->mMinHeight = minHeight;
- markDirty();
- }
- }
- inline float getMinHeight() const {
- return mCssStyle->mMinHeight;
- }
- inline void setMaxHeight(const float maxHeight) {
- if (mCssStyle->mMaxHeight != maxHeight) {
- mCssStyle->mMaxHeight = maxHeight;
- markDirty();
- }
- }
- inline float getMaxHeight() const {
- return mCssStyle->mMaxHeight;
- }
- inline void setDirection(const WXCoreDirection direction, const bool updating) {
- if (nullptr == mCssStyle) return;
-
- if (mCssStyle->mDirection != direction) {
- mCssStyle->mDirection = direction;
- markDirty();
- if (updating) {
- for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
- (*it)->markInheritableDirty();
- }
- }
- }
- }
- inline WXCoreDirection getDirection() const {
- if (mCssStyle == nullptr) {
- return WEEXCORE_CSS_DEFAULT_DIRECTION;
- }
- return mCssStyle->mDirection;
- }
-
- /** ================================ CSS direction For RTL =================================== **/
-
- void determineChildLayoutDirection(const WXCoreDirection direction);
-
- WXCoreDirection getLayoutDirectionFromPathNode();
-
- /** ================================ flex-style =================================== **/
- inline void setFlexDirection(const WXCoreFlexDirection flexDirection, const bool updating) {
- if (mCssStyle->mFlexDirection != flexDirection) {
- mCssStyle->mFlexDirection = flexDirection;
- markDirty();
- if (updating) {
- for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
- (*it)->markDirty(false);
- }
- }
- }
- }
- inline WXCoreFlexDirection getFlexDirection() const {
- return mCssStyle->mFlexDirection;
- }
- inline void setFlexWrap(const WXCoreFlexWrap flexWrap) {
- if (mCssStyle->mFlexWrap != flexWrap) {
- mCssStyle->mFlexWrap = flexWrap;
- markDirty();
- }
- }
- inline WXCoreFlexWrap getFlexWrap() const {
- return mCssStyle->mFlexWrap;
- }
- inline void setJustifyContent(const WXCoreJustifyContent justifyContent) {
- if (mCssStyle->mJustifyContent != justifyContent) {
- mCssStyle->mJustifyContent = justifyContent;
- }
- }
- inline WXCoreJustifyContent getJustifyContent() const {
- return mCssStyle->mJustifyContent;
- }
- inline void setAlignItems(const WXCoreAlignItems alignItems) {
- if (mCssStyle->mAlignItems != alignItems) {
- mCssStyle->mAlignItems = alignItems;
- markDirty();
- }
- }
- inline WXCoreAlignItems getAlignItems() const {
- return mCssStyle->mAlignItems;
- }
- inline void setAlignSelf(const WXCoreAlignSelf alignSelf) {
- if (mCssStyle->mAlignSelf != alignSelf) {
- mCssStyle->mAlignSelf = alignSelf;
- markDirty();
- }
- }
- inline WXCoreAlignSelf getAlignSelf() const {
- return mCssStyle->mAlignSelf;
- }
- virtual void set_flex(const float flex) {
- if (mCssStyle->mFlexGrow != flex) {
- mCssStyle->mFlexGrow = flex;
- markDirty();
- }
- }
- inline float getFlex() const {
- return mCssStyle->mFlexGrow;
- }
- /** ================================ layout-result =================================== **/
- inline float getLayoutWidth() const {
- return mLayoutResult->mLayoutSize.width;
- }
- inline float getLayoutHeight() const {
- return mLayoutResult->mLayoutSize.height;
- }
- inline float getLayoutPositionTop() const {
- return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeTop);
- }
- inline float getLayoutPositionBottom() const {
- return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeBottom);
- }
- inline float getLayoutPositionLeft() const {
- return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeLeft);
- }
- inline float getLayoutPositionRight() const {
- return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeRight);
- }
-
- virtual inline WXCoreDirection getLayoutDirection() const {
- if (nullptr == mLayoutResult) {
- return WEEXCORE_CSS_DEFAULT_DIRECTION;
- }
- return mLayoutResult->mLayoutDirection;
- }
- inline void setLayoutDirection(WXCoreDirection direction) {
- if (nullptr == mLayoutResult) return;
- mLayoutResult->mLayoutDirection = direction;
- }
- inline bool hasNewLayout() const {
- return mHasNewLayout;
- }
- inline bool isDirty() const {
- return dirty;
- }
- inline void markDirty(const bool recursion = true) {
- if (!isDirty()) {
- dirty = true;
- if (getParent() != nullptr && recursion) {
- getParent()->markDirty();
- }
- }
- }
-
- void markAllDirty() {
- markDirty(false);
- for (WXCoreLayoutNode* c : mChildList) {
- c->markAllDirty();
- }
- }
- bool markChildrenDirty(const bool updatedNode = false) {
- bool ret = false;
- if(getChildCount() == 0){
- if(measureFunc!= nullptr){
- ret = true;
- }
- }
- else {
- //isnan(mCssStyle->mStyleWidth) XOR updatedNode
- if(isnan(mCssStyle->mStyleWidth) != updatedNode){
- for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
- ret = ((*it)->markChildrenDirty() || ret) ;
- }
- }
- }
- dirty = ret || dirty;
- return ret;
- }
- void markInheritableDirty() {
- if (resetInheritableSet()) {
- // if some style was inherited from parent, reset those styles
- // then mark self dirty
- markDirty(false);
-
- // traverse children to mark dirty
- if(getChildCount() == 0){
- return;
- }
- else {
- for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
- (*it)->markInheritableDirty();
- }
- }
- }
- }
-
- /**
- * if some style was inherited from parent, reset those styles, then return true, eles return false
- */
- bool resetInheritableSet() {
- if (mCssStyle == nullptr || mLayoutResult == nullptr) return false;
-
- bool hasInheritedStyle = false;
- if (mCssStyle->mDirection == kDirectionInherit) {
- mLayoutResult->mLayoutDirection = kDirectionInherit;
- hasInheritedStyle = true;
- }
- return hasInheritedStyle;
- }
-
- inline void setHasNewLayout(const bool hasNewLayout) {
- this->mHasNewLayout = hasNewLayout;
- }
- inline float getLargestMainSize() const {
- float largestSize = 0;
- for (WXCoreFlexLine *flexLine : mFlexLines) {
- largestSize = std::max(largestSize, flexLine->mMainSize);
- }
- return largestSize + sumPaddingBorderAlongAxis(this, isMainAxisHorizontal(this));
- }
-
- inline void rewriteLayoutResult(float left, float top, float width, float height) {
- if (mLayoutResult != nullptr) {
- mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeLeft, left);
- mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeTop, top);
- mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeRight, left + width);
- mLayoutResult->mLayoutPosition.setPosition(kPositionEdgeBottom, top + height);
- mLayoutResult->mLayoutSize.width = width;
- mLayoutResult->mLayoutSize.height = height;
- }
- }
- };
- }
- #endif //WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H
- #endif
|