UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

170 lines 9.03 kB
import { WrapLayoutBase } from './wrap-layout-common'; import { View } from '../../core/view'; import { layout } from '../../../utils'; export * from './wrap-layout-common'; export class WrapLayout extends WrapLayoutBase { constructor() { super(...arguments); this._lengths = new Array(); } static getChildMeasureSpec(parentMode, parentLength, itemLength) { if (itemLength > 0) { return layout.makeMeasureSpec(itemLength, layout.EXACTLY); } else if (parentMode === layout.UNSPECIFIED) { return layout.makeMeasureSpec(0, layout.UNSPECIFIED); } else { return layout.makeMeasureSpec(parentLength, layout.AT_MOST); } } onMeasure(widthMeasureSpec, heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); let measureWidth = 0; let measureHeight = 0; const width = layout.getMeasureSpecSize(widthMeasureSpec); const widthMode = layout.getMeasureSpecMode(widthMeasureSpec); const height = layout.getMeasureSpecSize(heightMeasureSpec); const heightMode = layout.getMeasureSpecMode(heightMeasureSpec); const horizontalPaddingsAndMargins = this.effectivePaddingLeft + this.effectivePaddingRight + this.effectiveBorderLeftWidth + this.effectiveBorderRightWidth; const verticalPaddingsAndMargins = this.effectivePaddingTop + this.effectivePaddingBottom + this.effectiveBorderTopWidth + this.effectiveBorderBottomWidth; const availableWidth = widthMode === layout.UNSPECIFIED ? Number.MAX_VALUE : width - horizontalPaddingsAndMargins; const availableHeight = heightMode === layout.UNSPECIFIED ? Number.MAX_VALUE : height - verticalPaddingsAndMargins; const childWidthMeasureSpec = WrapLayout.getChildMeasureSpec(widthMode, availableWidth, this.effectiveItemWidth); const childHeightMeasureSpec = WrapLayout.getChildMeasureSpec(heightMode, availableHeight, this.effectiveItemHeight); let remainingWidth = availableWidth; let remainingHeight = availableHeight; this._lengths.length = 0; let rowOrColumn = 0; let maxLength = 0; const isVertical = this.orientation === 'vertical'; const useItemWidth = this.effectiveItemWidth > 0; const useItemHeight = this.effectiveItemHeight > 0; const itemWidth = this.effectiveItemWidth; const itemHeight = this.effectiveItemHeight; this.eachLayoutChild((child, last) => { const desiredSize = View.measureChild(this, child, childWidthMeasureSpec, childHeightMeasureSpec); const childMeasuredWidth = useItemWidth ? itemWidth : desiredSize.measuredWidth; const childMeasuredHeight = useItemHeight ? itemHeight : desiredSize.measuredHeight; const isFirst = this._lengths.length <= rowOrColumn; if (isVertical) { if (childMeasuredHeight > remainingHeight) { rowOrColumn++; maxLength = Math.max(maxLength, measureHeight); measureHeight = childMeasuredHeight; remainingHeight = availableHeight - childMeasuredHeight; this._lengths[isFirst ? rowOrColumn - 1 : rowOrColumn] = childMeasuredWidth; } else { remainingHeight -= childMeasuredHeight; measureHeight += childMeasuredHeight; } } else { if (childMeasuredWidth > remainingWidth) { rowOrColumn++; maxLength = Math.max(maxLength, measureWidth); measureWidth = childMeasuredWidth; remainingWidth = availableWidth - childMeasuredWidth; this._lengths[isFirst ? rowOrColumn - 1 : rowOrColumn] = childMeasuredHeight; } else { remainingWidth -= childMeasuredWidth; measureWidth += childMeasuredWidth; } } if (isFirst) { this._lengths[rowOrColumn] = isVertical ? childMeasuredWidth : childMeasuredHeight; } else { this._lengths[rowOrColumn] = Math.max(this._lengths[rowOrColumn], isVertical ? childMeasuredWidth : childMeasuredHeight); } }); if (isVertical) { measureHeight = Math.max(maxLength, measureHeight); this._lengths.forEach((value, index, array) => { measureWidth += value; }); } else { measureWidth = Math.max(maxLength, measureWidth); this._lengths.forEach((value, index, array) => { measureHeight += value; }); } measureWidth += horizontalPaddingsAndMargins; measureHeight += verticalPaddingsAndMargins; // Check against our minimum sizes measureWidth = Math.max(measureWidth, this.effectiveMinWidth); measureHeight = Math.max(measureHeight, this.effectiveMinHeight); const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0); const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0); this.setMeasuredDimension(widthAndState, heightAndState); } onLayout(left, top, right, bottom) { super.onLayout(left, top, right, bottom); const insets = this.getSafeAreaInsets(); const isVertical = this.orientation === 'vertical'; const paddingLeft = this.effectiveBorderLeftWidth + this.effectivePaddingLeft + insets.left; const paddingTop = this.effectiveBorderTopWidth + this.effectivePaddingTop + insets.top; const paddingRight = this.effectiveBorderRightWidth + this.effectivePaddingRight + insets.right; const paddingBottom = this.effectiveBorderBottomWidth + this.effectivePaddingBottom + insets.bottom; let childLeft = paddingLeft; let childTop = paddingTop; const childrenHeight = bottom - top - paddingBottom; const childrenWidth = right - left - paddingRight; let rowOrColumn = 0; this.eachLayoutChild((child, last) => { // Add margins because layoutChild will sustract them. // * density converts them to device pixels. let childHeight = child.getMeasuredHeight() + child.effectiveMarginTop + child.effectiveMarginBottom; let childWidth = child.getMeasuredWidth() + child.effectiveMarginLeft + child.effectiveMarginRight; const length = this._lengths[rowOrColumn]; if (isVertical) { childWidth = length; childHeight = this.effectiveItemHeight > 0 ? this.effectiveItemHeight : childHeight; const isFirst = childTop === paddingTop; if (childTop + childHeight > childrenHeight && childLeft + childWidth <= childrenWidth) { // Move to top. childTop = paddingTop; if (!isFirst) { // Move to right with current column width. childLeft += length; } // Move to next column. rowOrColumn++; // Take respective column width. childWidth = this._lengths[isFirst ? rowOrColumn - 1 : rowOrColumn]; } if (childLeft < childrenWidth && childTop < childrenHeight) { View.layoutChild(this, child, childLeft, childTop, childLeft + childWidth, childTop + childHeight); } // Move next child Top position to bottom. childTop += childHeight; } else { childWidth = this.effectiveItemWidth > 0 ? this.effectiveItemWidth : childWidth; childHeight = length; const isFirst = childLeft === paddingLeft; if (childLeft + childWidth > childrenWidth && childTop + childHeight <= childrenHeight) { // Move to left. childLeft = paddingLeft; if (!isFirst) { // Move to bottom with current row height. childTop += length; } // Move to next row. rowOrColumn++; // Take respective row height. childHeight = this._lengths[isFirst ? rowOrColumn - 1 : rowOrColumn]; } if (childLeft < childrenWidth && childTop < childrenHeight) { View.layoutChild(this, child, childLeft, childTop, childLeft + childWidth, childTop + childHeight); } // Move next child Left position to right. childLeft += childWidth; } }); } } //# sourceMappingURL=index.ios.js.map