Nez.UI.Table.layout C# (CSharp) Method

layout() public method

Positions and sizes children of the table using the cell associated with each child. The values given are the position within the parent and size of the table.
public layout ( float layoutX, float layoutY, float layoutWidth, float layoutHeight ) : void
layoutX float Layout x.
layoutY float Layout y.
layoutWidth float Layout width.
layoutHeight float Layout height.
return void
		void layout( float layoutX, float layoutY, float layoutWidth, float layoutHeight )
		{
			if( _sizeInvalid )
				computeSize();

			var cellCount = _cells.Count;
			var padLeft = _padLeft.get( this );
			var hpadding = padLeft + _padRight.get( this );
			var padTop = _padTop.get( this );
			var vpadding = padTop + _padBottom.get( this );

			int columns = _columns, rows = _rows;
			float[] expandWidth = _expandWidth, expandHeight = _expandHeight;
			float[] columnWidth = _columnWidth, rowHeight = _rowHeight;

			float totalExpandWidth = 0, totalExpandHeight = 0;
			for( var i = 0; i < columns; i++ )
				totalExpandWidth += expandWidth[i];
			for( var i = 0; i < rows; i++ )
				totalExpandHeight += expandHeight[i];

			// Size columns and rows between min and pref size using (preferred - min) size to weight distribution of extra space.
			float[] columnWeightedWidth;
			float totalGrowWidth = _tablePrefWidth - _tableMinWidth;
			if( totalGrowWidth == 0 )
			{
				columnWeightedWidth = _columnMinWidth;
			}
			else
			{
				var extraWidth = Math.Min( totalGrowWidth, Math.Max( 0, layoutWidth - _tableMinWidth ) );
				columnWeightedWidth = Table._columnWeightedWidth = ensureSize( Table._columnWeightedWidth, columns );
				float[] columnMinWidth = _columnMinWidth, columnPrefWidth = _columnPrefWidth;
				for( var i = 0; i < columns; i++ )
				{
					var growWidth = columnPrefWidth[i] - columnMinWidth[i];
					var growRatio = growWidth / totalGrowWidth;
					columnWeightedWidth[i] = columnMinWidth[i] + extraWidth * growRatio;
				}
			}

			float[] rowWeightedHeight;
			var totalGrowHeight = _tablePrefHeight - _tableMinHeight;
			if( totalGrowHeight == 0 )
			{
				rowWeightedHeight = _rowMinHeight;
			}
			else
			{
				rowWeightedHeight = Table._rowWeightedHeight = ensureSize( Table._rowWeightedHeight, rows );
				var extraHeight = Math.Min( totalGrowHeight, Math.Max( 0, layoutHeight - _tableMinHeight ) );
				float[] rowMinHeight = _rowMinHeight, rowPrefHeight = _rowPrefHeight;
				for( int i = 0; i < rows; i++ )
				{
					float growHeight = rowPrefHeight[i] - rowMinHeight[i];
					float growRatio = growHeight / totalGrowHeight;
					rowWeightedHeight[i] = rowMinHeight[i] + extraHeight * growRatio;
				}
			}

			// Determine element and cell sizes (before expand or fill).
			for( var i = 0; i < cellCount; i++ )
			{
				var cell = _cells[i];
				int column = cell.column, row = cell.row;

				var spannedWeightedWidth = 0f;
				var colspan = cell.colspan.Value;
				for( int ii = column, nn = ii + colspan; ii < nn; ii++ )
					spannedWeightedWidth += columnWeightedWidth[ii];
				var weightedHeight = rowWeightedHeight[row];

				var prefWidth = cell.prefWidth.get( cell.element );
				var prefHeight = cell.prefHeight.get( cell.element );
				var minWidth = cell.minWidth.get( cell.element );
				var minHeight = cell.minHeight.get( cell.element );
				var maxWidth = cell.maxWidth.get( cell.element );
				var maxHeight = cell.maxHeight.get( cell.element );

				if( prefWidth < minWidth )
					prefWidth = minWidth;
				if( prefHeight < minHeight )
					prefHeight = minHeight;
				if( maxWidth > 0 && prefWidth > maxWidth )
					prefWidth = maxWidth;
				if( maxHeight > 0 && prefHeight > maxHeight )
					prefHeight = maxHeight;

				cell.elementWidth = Math.Min( spannedWeightedWidth - cell.computedPadLeft - cell.computedPadRight, prefWidth );
				cell.elementHeight = Math.Min( weightedHeight - cell.computedPadTop - cell.computedPadBottom, prefHeight );

				if( colspan == 1 )
					columnWidth[column] = Math.Max( columnWidth[column], spannedWeightedWidth );
				rowHeight[row] = Math.Max( rowHeight[row], weightedHeight );
			}

			// distribute remaining space to any expanding columns/rows.
			if( totalExpandWidth > 0 )
			{
				var extra = layoutWidth - hpadding;
				for( var i = 0; i < columns; i++ )
					extra -= columnWidth[i];
				
				var used = 0f;
				var lastIndex = 0;
				for( var i = 0; i < columns; i++ )
				{
					if( expandWidth[i] == 0 )
						continue;
					var amount = extra * expandWidth[i] / totalExpandWidth;
					columnWidth[i] += amount;
					used += amount;
					lastIndex = i;
				}
				columnWidth[lastIndex] += extra - used;
			}

			if( totalExpandHeight > 0 )
			{
				var extra = layoutHeight - vpadding;
				for( var i = 0; i < rows; i++ )
					extra -= rowHeight[i];
				
				var used = 0f;
				var lastIndex = 0;
				for( var i = 0; i < rows; i++ )
				{
					if( expandHeight[i] == 0 )
						continue;
					
					var amount = extra * expandHeight[i] / totalExpandHeight;
					rowHeight[i] += amount;
					used += amount;
					lastIndex = i;
				}
				rowHeight[lastIndex] += extra - used;
			}

			// distribute any additional width added by colspanned cells to the columns spanned.
			for( var i = 0; i < cellCount; i++ )
			{
				var c = _cells[i];
				var colspan = c.colspan.Value;
				if( colspan == 1 )
					continue;

				var extraWidth = 0f;
				for( int column = c.column, nn = column + colspan; column < nn; column++ )
					extraWidth += columnWeightedWidth[column] - columnWidth[column];
				extraWidth -= Math.Max( 0, c.computedPadLeft + c.computedPadRight );

				extraWidth /= colspan;
				if( extraWidth > 0 )
				{
					for( int column = c.column, nn = column + colspan; column < nn; column++ )
						columnWidth[column] += extraWidth;
				}
			}

			// Determine table size.
			float tableWidth = hpadding, tableHeight = vpadding;
			for( var i = 0; i < columns; i++ )
				tableWidth += columnWidth[i];
			for( var i = 0; i < rows; i++ )
				tableHeight += rowHeight[i];

			// Position table within the container.
			var x = layoutX + padLeft;
			if( ( _align & AlignInternal.right ) != 0 )
				x += layoutWidth - tableWidth;
			else if( ( _align & AlignInternal.left ) == 0 ) // Center
				x += ( layoutWidth - tableWidth ) / 2;

			var y = layoutY + padTop; // bottom
			if( ( _align & AlignInternal.bottom ) != 0 )
				y += layoutHeight - tableHeight;
			else if( ( _align & AlignInternal.top ) == 0 ) // Center
				y += ( layoutHeight - tableHeight ) / 2;

			// position elements within cells.
			float currentX = x, currentY = y;
			for( var i = 0; i < cellCount; i++ )
			{
				var c = _cells[i];

				var spannedCellWidth = 0f;
				for( int column = c.column, nn = column + c.colspan.Value; column < nn; column++ )
					spannedCellWidth += columnWidth[column];
				spannedCellWidth -= c.computedPadLeft + c.computedPadRight;

				currentX += c.computedPadLeft;

				float fillX = c.fillX.Value, fillY = c.fillY.Value;
				if( fillX > 0 )
				{
					c.elementWidth = Math.Max( spannedCellWidth * fillX, c.minWidth.get( c.element ) );
					var maxWidth = c.maxWidth.get( c.element );
					if( maxWidth > 0 )
						c.elementWidth = Math.Min( c.elementWidth, maxWidth );
				}
				if( fillY > 0 )
				{
					c.elementHeight = Math.Max( rowHeight[c.row] * fillY - c.computedPadTop - c.computedPadBottom, c.minHeight.get( c.element ) );
					var maxHeight = c.maxHeight.get( c.element );
					if( maxHeight > 0 )
						c.elementHeight = Math.Min( c.elementHeight, maxHeight );
				}

				var cellAlign = c.align.Value;
				if( ( cellAlign & AlignInternal.left ) != 0 )
					c.elementX = currentX;
				else if( ( cellAlign & AlignInternal.right ) != 0 )
					c.elementX = currentX + spannedCellWidth - c.elementWidth;
				else
					c.elementX = currentX + ( spannedCellWidth - c.elementWidth ) / 2;

				if( ( cellAlign & AlignInternal.top ) != 0 )
					c.elementY = currentY + c.computedPadTop;
				else if( ( cellAlign & AlignInternal.bottom ) != 0 )
					c.elementY = currentY + rowHeight[c.row] - c.elementHeight - c.computedPadBottom;
				else
					c.elementY = currentY + ( rowHeight[c.row] - c.elementHeight + c.computedPadTop - c.computedPadBottom ) / 2;

				if( c.endRow )
				{
					currentX = x;
					currentY += rowHeight[c.row];
				}
				else
				{
					currentX += spannedCellWidth + c.computedPadRight;
				}
			}

			if( _tableDebug != TableDebug.None )
				computeDebugRects( x, y, layoutX, layoutY, layoutWidth, layoutHeight, tableWidth, tableHeight, hpadding, vpadding );
		}

Same methods

Table::layout ( ) : void