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

computeSize() public method

public computeSize ( ) : void
return void
		void computeSize()
		{
			_sizeInvalid = false;

			var cellCount = _cells.Count;

			// Implicitly End the row for layout purposes.
			if( cellCount > 0 && !_cells.Last().endRow )
			{
				endRow();
				_implicitEndRow = true;
			}
			else
			{
				_implicitEndRow = false;
			}

			int columns = _columns, rows = _rows;
			_columnWidth = ensureSize( _columnWidth, columns );
			_rowHeight = ensureSize( _rowHeight, rows );
			_columnMinWidth = ensureSize( _columnMinWidth, columns );
			_rowMinHeight = ensureSize( _rowMinHeight, rows );
			_columnPrefWidth = ensureSize( _columnPrefWidth, columns );
			_rowPrefHeight = ensureSize( _rowPrefHeight, rows );
			_expandWidth = ensureSize( _expandWidth, columns );
			_expandHeight = ensureSize( _expandHeight, rows );

			var spaceRightLast = 0f;
			for( var i = 0; i < cellCount; i++ )
			{
				var cell = _cells[i];
				int column = cell.column, row = cell.row, colspan = cell.colspan.Value;

				// Collect rows that expand and colspan=1 columns that expand.
				if( cell.expandY != 0 && _expandHeight[row] == 0 )
					_expandHeight[row] = cell.expandY.Value;
				if( colspan == 1 && cell.expandX != 0 && _expandWidth[column] == 0 )
					_expandWidth[column] = cell.expandX.Value;

				// Compute combined padding/spacing for cells.
				// Spacing between elements isn't additive, the larger is used. Also, no spacing around edges.
				cell.computedPadLeft = cell.padLeft.get( cell.element ) + ( column == 0 ? 0 : Math.Max( 0, cell.spaceLeft.get( cell.element ) - spaceRightLast ) );
				cell.computedPadTop = cell.padTop.get( cell.element );
				if( cell.cellAboveIndex != -1 )
				{
					var above = _cells[cell.cellAboveIndex];
					cell.computedPadTop += Math.Max( 0, cell.spaceTop.get( cell.element ) - above.spaceBottom.get( cell.element ) );
				}

				var spaceRight = cell.spaceRight.get( cell.element );
				cell.computedPadRight = cell.padRight.get( cell.element ) + ( ( column + colspan ) == columns ? 0 : spaceRight );
				cell.computedPadBottom = cell.padBottom.get( cell.element ) + ( row == rows - 1 ? 0 : cell.spaceBottom.get( cell.element ) );
				spaceRightLast = spaceRight;

				// Determine minimum and preferred cell sizes.
				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;

				if( colspan == 1 )
				{
					// Spanned column min and pref width is added later.
					var hpadding = cell.computedPadLeft + cell.computedPadRight;
					_columnPrefWidth[column] = Math.Max( _columnPrefWidth[column], prefWidth + hpadding );
					_columnMinWidth[column] = Math.Max( _columnMinWidth[column], minWidth + hpadding );
				}
				float vpadding = cell.computedPadTop + cell.computedPadBottom;
				_rowPrefHeight[row] = Math.Max( _rowPrefHeight[row], prefHeight + vpadding );
				_rowMinHeight[row] = Math.Max( _rowMinHeight[row], minHeight + vpadding );
			}

			float uniformMinWidth = 0, uniformMinHeight = 0;
			float uniformPrefWidth = 0, uniformPrefHeight = 0;
			for( var i = 0; i < cellCount; i++ )
			{
				var c = _cells[i];

				// Colspan with expand will expand all spanned columns if none of the spanned columns have expand.
				var expandX = c.expandX.Value;
				if( expandX != 0 )
				{
					int nn = c.column + c.colspan.Value;
					for( int ii = c.column; ii < nn; ii++ )
						if( _expandWidth[ii] != 0 )
							goto outer;
					for( int ii = c.column; ii < nn; ii++ )
						_expandWidth[ii] = expandX;
				}
				outer:
				{}

				// Collect uniform sizes.
				if( c.uniformX.HasValue && c.uniformX.Value && c.colspan == 1 )
				{
					float hpadding = c.computedPadLeft + c.computedPadRight;
					uniformMinWidth = Math.Max( uniformMinWidth, _columnMinWidth[c.column] - hpadding );
					uniformPrefWidth = Math.Max( uniformPrefWidth, _columnPrefWidth[c.column] - hpadding );
				}

				if( c.uniformY.HasValue && c.uniformY.Value )
				{
					float vpadding = c.computedPadTop + c.computedPadBottom;
					uniformMinHeight = Math.Max( uniformMinHeight, _rowMinHeight[c.row] - vpadding );
					uniformPrefHeight = Math.Max( uniformPrefHeight, _rowPrefHeight[c.row] - vpadding );
				}
			}

			// Size uniform cells to the same width/height.
			if( uniformPrefWidth > 0 || uniformPrefHeight > 0 )
			{
				for( var i = 0; i < cellCount; i++ )
				{
					var c = _cells[i];
					if( uniformPrefWidth > 0 && c.uniformX.HasValue && c.uniformX.Value && c.colspan == 1 )
					{
						var hpadding = c.computedPadLeft + c.computedPadRight;
						_columnMinWidth[c.column] = uniformMinWidth + hpadding;
						_columnPrefWidth[c.column] = uniformPrefWidth + hpadding;
					}

					if( uniformPrefHeight > 0 && c.uniformY.HasValue && c.uniformY.Value )
					{
						var vpadding = c.computedPadTop + c.computedPadBottom;
						_rowMinHeight[c.row] = uniformMinHeight + vpadding;
						_rowPrefHeight[c.row] = uniformPrefHeight + vpadding;
					}
				}
			}

			// Distribute any additional min and pref 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 a = c.element;
				var minWidth = c.minWidth.get( a );
				var prefWidth = c.prefWidth.get( a );
				var maxWidth = c.maxWidth.get( a );
				if( prefWidth < minWidth )
					prefWidth = minWidth;
				if( maxWidth > 0 && prefWidth > maxWidth )
					prefWidth = maxWidth;

				float spannedMinWidth = -( c.computedPadLeft + c.computedPadRight ), spannedPrefWidth = spannedMinWidth;
				var totalExpandWidth = 0f;
				for( int ii = c.column, nn = ii + colspan; ii < nn; ii++ )
				{
					spannedMinWidth += _columnMinWidth[ii];
					spannedPrefWidth += _columnPrefWidth[ii];
					totalExpandWidth += _expandWidth[ii]; // Distribute extra space using expand, if any columns have expand.
				}

				var extraMinWidth = Math.Max( 0, minWidth - spannedMinWidth );
				var extraPrefWidth = Math.Max( 0, prefWidth - spannedPrefWidth );
				for( int ii = c.column, nn = ii + colspan; ii < nn; ii++ )
				{
					float ratio = totalExpandWidth == 0 ? 1f / colspan : _expandWidth[ii] / totalExpandWidth;
					_columnMinWidth[ii] += extraMinWidth * ratio;
					_columnPrefWidth[ii] += extraPrefWidth * ratio;
				}
			}

			// Determine table min and pref size.
			_tableMinWidth = 0;
			_tableMinHeight = 0;
			_tablePrefWidth = 0;
			_tablePrefHeight = 0;
			for( var i = 0; i < columns; i++ )
			{
				_tableMinWidth += _columnMinWidth[i];
				_tablePrefWidth += _columnPrefWidth[i];
			}

			for( var i = 0; i < rows; i++ )
			{
				_tableMinHeight += _rowMinHeight[i];
				_tablePrefHeight += Math.Max( _rowMinHeight[i], _rowPrefHeight[i] );
			}

			var hpadding_ = _padLeft.get( this ) + _padRight.get( this );
			var vpadding_ = _padTop.get( this ) + _padBottom.get( this );
			_tableMinWidth = _tableMinWidth + hpadding_;
			_tableMinHeight = _tableMinHeight + vpadding_;
			_tablePrefWidth = Math.Max( _tablePrefWidth + hpadding_, _tableMinWidth );
			_tablePrefHeight = Math.Max( _tablePrefHeight + vpadding_, _tableMinHeight );
		}