Example #1
0
        public void setColumnWidth(int column, TableColumnWidth value)
        {
            if (this._columnWidths.getOrDefault(column) == value)
            {
                return;
            }

            this._columnWidths[column] = value;
            this.markNeedsLayout();
            ;
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        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);
        }
Example #6
0
 public MinColumnWidth(
     TableColumnWidth a, TableColumnWidth b)
 {
     this.a = a;
     this.b = b;
 }
Example #7
0
        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);
        }