public void setColumnWidth(int column, TableColumnWidth value) { if (this._columnWidths.getOrDefault(column) == value) { return; } this._columnWidths[column] = value; this.markNeedsLayout(); ; }
protected override float computeMaxIntrinsicWidth(float height) { D.assert(this._children.Count == this.rows * this.columns); float totalMaxWidth = 0.0f; for (int x = 0; x < this.columns; x++) { TableColumnWidth columnWidth = this._columnWidths.getOrDefault(x) ?? this.defaultColumnWidth; List <RenderBox> columnCells = this.column(x); totalMaxWidth += columnWidth.maxIntrinsicWidth(columnCells, float.PositiveInfinity); } return(totalMaxWidth); }
protected internal override float computeMinIntrinsicWidth(float height) { D.assert(_children.Count == rows * columns); float totalMinWidth = 0.0f; for (int x = 0; x < columns; x++) { TableColumnWidth columnWidth = _columnWidths.getOrDefault(x) ?? defaultColumnWidth; List <RenderBox> columnCells = column(x); totalMinWidth += columnWidth.minIntrinsicWidth(columnCells, float.PositiveInfinity); } return(totalMinWidth); }
public RenderTable( int?columns = null, int?rows = null, Dictionary <int, TableColumnWidth> columnWidths = null, TableColumnWidth defaultColumnWidth = null, TableBorder border = null, List <Decoration> rowDecorations = null, ImageConfiguration configuration = null, TableCellVerticalAlignment defaultVerticalAlignment = TableCellVerticalAlignment.top, TextBaseline?textBaseline = null, List <List <RenderBox> > children = null ) { defaultColumnWidth = defaultColumnWidth ?? new FlexColumnWidth(1.0f); configuration = configuration ?? ImageConfiguration.empty; D.assert(columns == null || columns >= 0); D.assert(rows == null || rows >= 0); D.assert(rows == null || children == null); this._columns = columns ?? (children != null && children.isNotEmpty() ? children.First().Count : 0); this._rows = rows ?? 0; this._children = new List <RenderBox>(); for (int i = 0; i < this._columns * this._rows; i++) { this._children.Add(null); } this._columnWidths = columnWidths ?? new Dictionary <int, TableColumnWidth>(); this._defaultColumnWidth = defaultColumnWidth; this._border = border; this.rowDecorations = rowDecorations; this._configuration = configuration; this._defaultVerticalAlignment = defaultVerticalAlignment; this._textBaseline = textBaseline; if (children != null) { foreach (List <RenderBox> row in children) { this.addRow(row); } } }
List <float> _computeColumnWidths(BoxConstraints constraints) { D.assert(constraints != null); D.assert(this._children.Count == this.rows * this.columns); List <float> widths = new List <float>(); List <float> minWidths = new List <float>(); List <float?> flexes = new List <float?>(); for (int i = 0; i < this.columns; i++) { widths.Add(0.0f); minWidths.Add(0.0f); flexes.Add(null); } float tableWidth = 0.0f; float?unflexedTableWidth = 0.0f; float totalFlex = 0.0f; for (int x = 0; x < this.columns; x++) { TableColumnWidth columnWidth = this._columnWidths.getOrDefault(x) ?? this.defaultColumnWidth; List <RenderBox> columnCells = this.column(x); float maxIntrinsicWidth = columnWidth.maxIntrinsicWidth(columnCells, constraints.maxWidth); D.assert(maxIntrinsicWidth.isFinite()); D.assert(maxIntrinsicWidth >= 0.0f); widths[x] = maxIntrinsicWidth; tableWidth += maxIntrinsicWidth; float minIntrinsicWidth = columnWidth.minIntrinsicWidth(columnCells, constraints.maxWidth); D.assert(minIntrinsicWidth.isFinite()); D.assert(minIntrinsicWidth >= 0.0f); minWidths[x] = minIntrinsicWidth; D.assert(maxIntrinsicWidth >= minIntrinsicWidth); float?flex = columnWidth.flex(columnCells); if (flex != null) { D.assert(flex.Value.isFinite()); D.assert(flex.Value > 0.0f); flexes[x] = flex; totalFlex += flex.Value; } else { unflexedTableWidth += maxIntrinsicWidth; } } D.assert(!widths.Any((float value) => { return(value == null); })); float maxWidthConstraint = constraints.maxWidth; float minWidthConstraint = constraints.minWidth; if (totalFlex > 0.0f) { float targetWidth = 0.0f; if (maxWidthConstraint.isFinite()) { targetWidth = maxWidthConstraint; } else { targetWidth = minWidthConstraint; } if (tableWidth < targetWidth) { float remainingWidth = targetWidth - unflexedTableWidth.Value; D.assert(remainingWidth.isFinite()); D.assert(remainingWidth >= 0.0f); for (int x = 0; x < this.columns; x++) { if (flexes[x] != null) { float flexedWidth = remainingWidth * flexes[x].Value / totalFlex; D.assert(flexedWidth.isFinite()); D.assert(flexedWidth >= 0.0f); if (widths[x] < flexedWidth) { float delta = flexedWidth - widths[x]; tableWidth += delta; widths[x] = flexedWidth; } } } D.assert(tableWidth >= targetWidth); } } else if (tableWidth < minWidthConstraint) { float delta = (minWidthConstraint - tableWidth) / this.columns; for (int x = 0; x < this.columns; x++) { widths[x] += delta; } tableWidth = minWidthConstraint; } D.assert(() => { unflexedTableWidth = null; return(true); }); if (tableWidth > maxWidthConstraint) { float deficit = tableWidth - maxWidthConstraint; int availableColumns = this.columns; while (deficit > 0.0f && totalFlex > 0.0f) { float newTotalFlex = 0.0f; for (int x = 0; x < this.columns; x++) { if (flexes[x] != null) { float newWidth = widths[x] - deficit * flexes[x].Value / totalFlex; D.assert(newWidth.isFinite()); if (newWidth <= minWidths[x]) { deficit -= widths[x] - minWidths[x]; widths[x] = minWidths[x]; flexes[x] = null; availableColumns -= 1; } else { deficit -= widths[x] - newWidth; widths[x] = newWidth; newTotalFlex += flexes[x].Value; } D.assert(widths[x] >= 0.0f); } } totalFlex = newTotalFlex; } if (deficit > 0.0f) { do { float delta = deficit / availableColumns; int newAvailableColumns = 0; for (int x = 0; x < this.columns; x++) { float availableDelta = widths[x] - minWidths[x]; if (availableDelta > 0.0f) { if (availableDelta <= delta) { deficit -= widths[x] - minWidths[x]; widths[x] = minWidths[x]; } else { deficit -= availableDelta; widths[x] -= availableDelta; newAvailableColumns += 1; } } } availableColumns = newAvailableColumns; } while (deficit > 0.0f && availableColumns > 0); } } return(widths); }
public MinColumnWidth( TableColumnWidth a, TableColumnWidth b) { this.a = a; this.b = b; }
List <float> _computeColumnWidths(BoxConstraints constraints) { D.assert(constraints != null); D.assert(_children.Count == rows * columns); List <float> widths = new List <float>(); List <float> minWidths = new List <float>(); List <float?> flexes = new List <float?>(); for (int i = 0; i < columns; i++) { widths.Add(0.0f); minWidths.Add(0.0f); flexes.Add(null); } float tableWidth = 0.0f; float?unflexedTableWidth = 0.0f; float totalFlex = 0.0f; for (int x = 0; x < columns; x++) { TableColumnWidth columnWidth = _columnWidths.getOrDefault(x) ?? defaultColumnWidth; List <RenderBox> columnCells = column(x); float maxIntrinsicWidth = columnWidth.maxIntrinsicWidth(columnCells, constraints.maxWidth); D.assert(maxIntrinsicWidth.isFinite()); D.assert(maxIntrinsicWidth >= 0.0f); widths[x] = maxIntrinsicWidth; tableWidth += maxIntrinsicWidth; float minIntrinsicWidth = columnWidth.minIntrinsicWidth(columnCells, constraints.maxWidth); D.assert(minIntrinsicWidth.isFinite()); D.assert(minIntrinsicWidth >= 0.0f); minWidths[x] = minIntrinsicWidth; D.assert(maxIntrinsicWidth >= minIntrinsicWidth); float?flex = columnWidth.flex(columnCells); if (flex != null) { D.assert(flex.Value.isFinite()); D.assert(flex.Value > 0.0f); flexes[x] = flex; totalFlex += flex.Value; } else { unflexedTableWidth += maxIntrinsicWidth; } } float maxWidthConstraint = constraints.maxWidth; float minWidthConstraint = constraints.minWidth; if (totalFlex > 0.0f) { float targetWidth = 0.0f; if (maxWidthConstraint.isFinite()) { targetWidth = maxWidthConstraint; } else { targetWidth = minWidthConstraint; } if (tableWidth < targetWidth) { float remainingWidth = targetWidth - unflexedTableWidth.Value; D.assert(remainingWidth.isFinite()); D.assert(remainingWidth >= 0.0f); for (int x = 0; x < columns; x++) { if (flexes[x] != null) { float flexedWidth = remainingWidth * flexes[x].Value / totalFlex; D.assert(flexedWidth.isFinite()); D.assert(flexedWidth >= 0.0f); if (widths[x] < flexedWidth) { float delta = flexedWidth - widths[x]; tableWidth += delta; widths[x] = flexedWidth; } } } D.assert(tableWidth + foundation_.precisionErrorTolerance >= targetWidth); } } else if (tableWidth < minWidthConstraint) { float delta = (minWidthConstraint - tableWidth) / columns; for (int x = 0; x < columns; x++) { widths[x] += delta; } tableWidth = minWidthConstraint; } D.assert(() => { unflexedTableWidth = null; return(true); }); if (tableWidth > maxWidthConstraint) { float deficit = tableWidth - maxWidthConstraint; int availableColumns = columns; //(Xingwei Zhu) this deficit is double and set to be 0.00000001f in flutter. //since we use float by default, making it larger should make sense in most cases while (deficit > foundation_.precisionErrorTolerance && totalFlex > foundation_.precisionErrorTolerance) { float newTotalFlex = 0.0f; for (int x = 0; x < columns; x++) { if (flexes[x] != null) { //(Xingwei Zhu) in case deficit * flexes[x].Value / totalFlex => 0 if deficit is really small, leading to dead loop, //we amend it with a default larger value to ensure that this loop will eventually end float newWidth = widths[x] - Mathf.Max(foundation_.precisionErrorTolerance, deficit * flexes[x].Value / totalFlex); D.assert(newWidth.isFinite()); if (newWidth <= minWidths[x]) { deficit -= widths[x] - minWidths[x]; widths[x] = minWidths[x]; flexes[x] = null; availableColumns -= 1; } else { deficit -= widths[x] - newWidth; widths[x] = newWidth; newTotalFlex += flexes[x].Value; } D.assert(widths[x] >= 0.0f); } } totalFlex = newTotalFlex; } while (deficit > foundation_.precisionErrorTolerance && availableColumns > 0) { float delta = deficit / availableColumns; D.assert(delta != 0); int newAvailableColumns = 0; for (int x = 0; x < columns; x++) { float availableDelta = widths[x] - minWidths[x]; if (availableDelta > 0.0f) { if (availableDelta <= delta) { deficit -= widths[x] - minWidths[x]; widths[x] = minWidths[x]; } else { deficit -= availableDelta; widths[x] -= availableDelta; newAvailableColumns += 1; } } } availableColumns = newAvailableColumns; } } return(widths); }