diff --git a/lib/src/manager/state/column_state.dart b/lib/src/manager/state/column_state.dart index 6d6d31821..3c9e5316e 100644 --- a/lib/src/manager/state/column_state.dart +++ b/lib/src/manager/state/column_state.dart @@ -1,7 +1,10 @@ import 'dart:collection'; +import 'dart:math' as math; import 'package:flutter/material.dart'; -import 'package:pluto_grid_plus/pluto_grid_plus.dart'; + +import '../../../pluto_grid_plus.dart'; +import '../../ui/cells/pluto_default_cell.dart'; abstract class IColumnState { /// Columns provided at grid start. @@ -571,47 +574,72 @@ mixin ColumnState implements IPlutoGridState { @override void autoFitColumn(BuildContext context, PlutoColumn column) { - final String maxValue = refRows.fold('', (previousValue, element) { - final value = column.formattedValueForDisplay( - element.cells.entries - .firstWhere((element) => element.key == column.field) - .value - .value, - ); + String maxValue = ''; + bool hasExpandableRowGroup = false; + for (final row in refRows) { + final cell = row.cells.entries + .firstWhere((element) => element.key == column.field) + .value; + var value = column.formattedValueForDisplay(cell.value); + if (hasRowGroups) { + if (PlutoDefaultCell.showGroupCount(rowGroupDelegate!, cell)) { + final groupCountValue = + PlutoDefaultCell.groupCountText(rowGroupDelegate!, row); + if (groupCountValue.isNotEmpty) { + value = '$value $groupCountValue'; + } + } - if (previousValue.length < value.length) { - return value; + hasExpandableRowGroup |= + PlutoDefaultCell.canExpand(rowGroupDelegate!, cell); } - - return previousValue; - }); + if (maxValue.length < value.length) { + maxValue = value; + } + } // Get size after rendering virtually // https://stackoverflow.com/questions/54351655/flutter-textfield-width-should-match-width-of-contained-text - TextSpan textSpan = TextSpan( - style: DefaultTextStyle.of(context).style, - text: maxValue, - ); - - TextPainter textPainter = TextPainter( - text: textSpan, - textDirection: TextDirection.ltr, - ); - - textPainter.layout(); - - // todo : Apply (popup type icon, checkbox, drag indicator, renderer) + final titleTextWidth = + _visualTextWidth(column.title, style.columnTextStyle); + final maxValueTextWidth = _visualTextWidth(maxValue, style.cellTextStyle); + + // todo : Handle (renderer) width + + final calculatedTileWidth = titleTextWidth - + column.width + + [ + (column.titlePadding ?? style.defaultColumnTitlePadding).horizontal, + if (column.enableRowChecked) + _getEffectiveButtonWidth(context, checkBox: true), + if (column.isShowRightIcon) style.iconSize, + 8, + ].reduce((acc, a) => acc + a); + + final calculatedCellWidth = maxValueTextWidth - + column.width + + [ + (column.cellPadding ?? style.defaultCellPadding).horizontal, + if (hasExpandableRowGroup) _getEffectiveButtonWidth(context), + if (column.enableRowChecked) + _getEffectiveButtonWidth(context, checkBox: true), + if (column.isShowRightIcon) style.iconSize, + 2, + ].reduce((acc, a) => acc + a); - EdgeInsets cellPadding = - column.cellPadding ?? configuration.style.defaultCellPadding; + resizeColumn(column, math.max(calculatedTileWidth, calculatedCellWidth)); + } - resizeColumn( - column, - textPainter.width - - column.width + - (cellPadding.left + cellPadding.right) + - 2, - ); + double _visualTextWidth(String text, TextStyle style) { + if (text.isEmpty) return 0; + final painter = TextPainter( + text: TextSpan( + style: style, + text: text, + ), + textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr, + )..layout(); + return painter.width; } @override @@ -1031,4 +1059,22 @@ mixin ColumnState implements IPlutoGridState { return resizeHelper.update(); } + + double _getEffectiveButtonWidth(BuildContext context, + {bool checkBox = false}) { + final theme = Theme.of(context); + late double width; + switch (theme.materialTapTargetSize) { + case MaterialTapTargetSize.padded: + width = kMinInteractiveDimension; + break; + case MaterialTapTargetSize.shrinkWrap: + width = kMinInteractiveDimension - 8.0; + break; + } + if (!checkBox) { + return width; + } + return width + theme.visualDensity.baseSizeAdjustment.dx; + } } diff --git a/lib/src/ui/cells/pluto_default_cell.dart b/lib/src/ui/cells/pluto_default_cell.dart index 09d738cd0..00386629e 100644 --- a/lib/src/ui/cells/pluto_default_cell.dart +++ b/lib/src/ui/cells/pluto_default_cell.dart @@ -27,6 +27,37 @@ class PlutoDefaultCell extends PlutoStatefulWidget { @override State createState() => _PlutoDefaultCellState(); + + static String groupCountText(PlutoRowGroupDelegate delegate, PlutoRow row) { + final compactCount = delegate.enableCompactCount; + final count = compactCount + ? delegate.compactNumber(row.type.group.children.length) + : row.type.group.children.length.toString(); + return '($count)'; + } + + static TextStyle groupCountTextStyle(PlutoGridStyleConfig style) { + return style.cellTextStyle.copyWith( + decoration: TextDecoration.none, + fontWeight: FontWeight.normal, + ); + } + + static bool canExpand(PlutoRowGroupDelegate? delegate, PlutoCell cell) { + if (delegate == null) return false; + if (!cell.row.type.isGroup || !delegate.enabled) { + return false; + } + return delegate.isExpandableCell(cell); + } + + static bool showGroupCount(PlutoRowGroupDelegate? delegate, PlutoCell cell) { + if (delegate == null) return false; + return delegate.enabled && + delegate.isExpandableCell(cell) && + cell.row.type.isGroup && + delegate.showCount; + } } class _PlutoDefaultCellState extends PlutoStateWithChange { @@ -41,24 +72,16 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { @override PlutoGridStateManager get stateManager => widget.stateManager; - bool get _canExpand { - if (!widget.row.type.isGroup || !stateManager.enabledRowGroups) { - return false; - } - - return _isExpandableCell; - } - - bool get _isExpandableCell => - stateManager.rowGroupDelegate!.isExpandableCell(widget.cell); - bool get _showSpacing { if (!stateManager.enabledRowGroups || !stateManager.rowGroupDelegate!.showFirstExpandableIcon) { return false; } - if (_canExpand) return true; + if (PlutoDefaultCell.canExpand( + stateManager.rowGroupDelegate!, widget.cell)) { + return true; + } final parentCell = widget.row.parent?.cells[widget.column.field]; @@ -68,19 +91,6 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { bool get _isEmptyGroup => widget.row.type.group.children.isEmpty; - bool get _showGroupCount => - stateManager.enabledRowGroups && - _isExpandableCell && - widget.row.type.isGroup && - stateManager.rowGroupDelegate!.showCount; - - String get _groupCount => _compactCount - ? stateManager.rowGroupDelegate! - .compactNumber(widget.row.type.group.children.length) - : widget.row.type.group.children.length.toString(); - - bool get _compactCount => stateManager.rowGroupDelegate!.enableCompactCount; - @override void initState() { super.initState(); @@ -140,7 +150,8 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { } Widget? expandIcon; - if (_canExpand) { + if (PlutoDefaultCell.canExpand( + stateManager.rowGroupDelegate, widget.cell)) { expandIcon = IconButton( onPressed: _isEmptyGroup ? null : _handleToggleExpandedRowGroup, icon: _isEmptyGroup @@ -187,13 +198,12 @@ class _PlutoDefaultCellState extends PlutoStateWithChange { if (spacingWidget != null) spacingWidget, if (expandIcon != null) expandIcon, Expanded(child: cellWidget), - if (_showGroupCount) + if (PlutoDefaultCell.showGroupCount( + stateManager.rowGroupDelegate, widget.cell)) Text( - '($_groupCount)', - style: stateManager.configuration.style.cellTextStyle.copyWith( - decoration: TextDecoration.none, - fontWeight: FontWeight.normal, - ), + PlutoDefaultCell.groupCountText( + stateManager.rowGroupDelegate!, widget.row), + style: PlutoDefaultCell.groupCountTextStyle(stateManager.style), ), ]); }