diff --git a/lib/src/manager/pluto_change_notifier_filter.dart b/lib/src/manager/pluto_change_notifier_filter.dart index 0ec6ed886..6a15ef96e 100644 --- a/lib/src/manager/pluto_change_notifier_filter.dart +++ b/lib/src/manager/pluto_change_notifier_filter.dart @@ -113,8 +113,8 @@ abstract class PlutoChangeNotifierFilterResolver { stateManager.setShowColumnFooter.hashCode: 'setShowColumnFooter', stateManager.setShowColumnFilter.hashCode: 'setShowColumnFilter', stateManager.setShowLoading.hashCode: 'setShowLoading', - stateManager.performLayoutOnPostFrame.hashCode: - 'performLayoutOnPostFrame', + stateManager.notifyChangedShowFrozenColumn.hashCode: + 'notifyChangedShowFrozenColumn', /// pagination_state stateManager.setPageSize.hashCode: 'setPageSize', @@ -197,7 +197,7 @@ class PlutoNotifierFilterResolverDefault stateManager.removeColumns.hashCode, stateManager.moveColumn.hashCode, stateManager.hideColumn.hashCode, - stateManager.performLayoutOnPostFrame.hashCode, + stateManager.notifyChangedShowFrozenColumn.hashCode, }; } @@ -210,7 +210,7 @@ class PlutoNotifierFilterResolverDefault stateManager.hideColumn.hashCode, stateManager.setShowColumnGroups.hashCode, stateManager.removeColumnsInColumnGroup.hashCode, - stateManager.performLayoutOnPostFrame.hashCode, + stateManager.notifyChangedShowFrozenColumn.hashCode, }; } @@ -237,7 +237,7 @@ class PlutoNotifierFilterResolverDefault stateManager.moveRowsByIndex.hashCode, stateManager.setRowGroup.hashCode, stateManager.toggleExpandedRowGroup.hashCode, - stateManager.performLayoutOnPostFrame.hashCode, + stateManager.notifyChangedShowFrozenColumn.hashCode, stateManager.setPage.hashCode, stateManager.setPageSize.hashCode, }; diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index d7a3ab771..0732270bb 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -118,9 +118,9 @@ abstract class ILayoutState { void notifyResizingListeners(); - void setTextDirection(TextDirection textDirection); + void notifyChangedShowFrozenColumn(); - void performLayoutOnPostFrame(); + void setTextDirection(TextDirection textDirection); @visibleForTesting void setGridGlobalOffset(Offset offset); @@ -396,22 +396,22 @@ mixin LayoutState implements IPlutoGridState { @override void setLayout(BoxConstraints size) { - final showFrozenColumn = shouldShowFrozenColumns(size.maxWidth); - final bool changedShowFrozenColumn = showFrozenColumn != showFrozenColumn; - final bool changedMaxWidth = maxWidth != size.maxWidth; + final firstLayout = maxWidth == null; + final changedSize = _updateSize(size, firstLayout); + final changedShowFrozen = _updateShowFrozenColumn( + size: size, + firstLayout: firstLayout, + changedSize: changedSize, + ); + final bool updateVisibility = + changedShowFrozen || firstLayout || changedSize; + final bool notifyResizing = !firstLayout && changedSize; - _state._maxWidth = size.maxWidth; - _state._maxHeight = size.maxHeight; - _state._showFrozenColumn = showFrozenColumn; - _state._gridGlobalOffset = null; + if (updateVisibility) updateVisibilityLayout(); - if (changedShowFrozenColumn || changedMaxWidth) { - updateVisibilityLayout(); + if (notifyResizing) notifyResizingListeners(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - notifyResizingListeners(); - }); - } + if (changedShowFrozen) notifyChangedShowFrozenColumn(); if (enableColumnsAutoSize && !activatedColumnsAutoSize) { activateColumnsAutoSize(); @@ -498,13 +498,13 @@ mixin LayoutState implements IPlutoGridState { } @override - void setTextDirection(TextDirection textDirection) { - _state._textDirection = textDirection; + void notifyChangedShowFrozenColumn() { + notifyListeners(true, notifyChangedShowFrozenColumn.hashCode); } @override - void performLayoutOnPostFrame() { - notifyListenersOnPostFrame(true, performLayoutOnPostFrame.hashCode); + void setTextDirection(TextDirection textDirection) { + _state._textDirection = textDirection; } @override @@ -512,4 +512,32 @@ mixin LayoutState implements IPlutoGridState { void setGridGlobalOffset(Offset offset) { _state._gridGlobalOffset = offset; } + + bool _updateSize(BoxConstraints size, bool firstLayout) { + final changedMaxWidth = !firstLayout && maxWidth != size.maxWidth; + + _state._maxWidth = size.maxWidth; + _state._maxHeight = size.maxHeight; + + return changedMaxWidth; + } + + bool _updateShowFrozenColumn({ + required BoxConstraints size, + required bool firstLayout, + required bool changedSize, + }) { + final updateShowFrozen = firstLayout || changedSize; + + final showFrozen = updateShowFrozen + ? shouldShowFrozenColumns(size.maxWidth) + : _state._showFrozenColumn!; + + final changedShowFrozen = + !firstLayout && _state._showFrozenColumn != showFrozen; + + _state._showFrozenColumn = showFrozen; + + return changedShowFrozen; + } } diff --git a/lib/src/pluto_grid.dart b/lib/src/pluto_grid.dart index 82dd9674f..54d8e96ee 100644 --- a/lib/src/pluto_grid.dart +++ b/lib/src/pluto_grid.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -605,175 +606,181 @@ class PlutoGridState extends PlutoStateWithChange { @override Widget build(BuildContext context) { - final style = _stateManager.style; - - final bool showLeftFrozen = - _stateManager.showFrozenColumn && _stateManager.hasLeftFrozenColumns; - - final bool showRightFrozen = - _stateManager.showFrozenColumn && _stateManager.hasRightFrozenColumns; - - final bool showColumnRowDivider = - _stateManager.showColumnTitle || _stateManager.showColumnFilter; - - final bool showColumnFooter = _stateManager.showColumnFooter; - return FocusScope( onFocusChange: _stateManager.setKeepFocus, onKey: _handleGridFocusOnKey, child: _GridContainer( stateManager: _stateManager, - child: CustomMultiChildLayout( - key: _stateManager.gridKey, - delegate: PlutoGridLayoutDelegate( - _stateManager, - Directionality.of(context), - ), - children: [ - /// Body columns and rows. - LayoutId( - id: _StackName.bodyRows, - child: PlutoBodyRows(_stateManager), - ), - LayoutId( - id: _StackName.bodyColumns, - child: PlutoBodyColumns(_stateManager), - ), + child: LayoutBuilder( + builder: (c, size) { + _stateManager.setLayout(size); - /// Body columns footer. - if (showColumnFooter) - LayoutId( - id: _StackName.bodyColumnFooters, - child: PlutoBodyColumnsFooter(stateManager), - ), + final style = _stateManager.style; - /// Left columns and rows. - if (showLeftFrozen) ...[ - LayoutId( - id: _StackName.leftFrozenColumns, - child: PlutoLeftFrozenColumns(_stateManager), - ), - LayoutId( - id: _StackName.leftFrozenRows, - child: PlutoLeftFrozenRows(_stateManager)), - LayoutId( - id: _StackName.leftFrozenDivider, - child: PlutoShadowLine( - axis: Axis.vertical, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - ), - ), - if (showColumnFooter) - LayoutId( - id: _StackName.leftFrozenColumnFooters, - child: PlutoLeftFrozenColumnsFooter(stateManager), - ), - ], + final bool showLeftFrozen = _stateManager.showFrozenColumn && + _stateManager.hasLeftFrozenColumns; - /// Right columns and rows. - if (showRightFrozen) ...[ - LayoutId( - id: _StackName.rightFrozenColumns, - child: PlutoRightFrozenColumns(_stateManager), - ), - LayoutId( - id: _StackName.rightFrozenRows, - child: PlutoRightFrozenRows(_stateManager)), - LayoutId( - id: _StackName.rightFrozenDivider, - child: PlutoShadowLine( - axis: Axis.vertical, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - reverse: true, - ), - ), - if (showColumnFooter) - LayoutId( - id: _StackName.rightFrozenColumnFooters, - child: PlutoRightFrozenColumnsFooter(stateManager), - ), - ], - - /// Column and row divider. - if (showColumnRowDivider) - LayoutId( - id: _StackName.columnRowDivider, - child: PlutoShadowLine( - axis: Axis.horizontal, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - ), - ), + final bool showRightFrozen = _stateManager.showFrozenColumn && + _stateManager.hasRightFrozenColumns; - /// Header and divider. - if (_stateManager.showHeader) ...[ - LayoutId( - id: _StackName.headerDivider, - child: PlutoShadowLine( - axis: Axis.horizontal, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - ), - ), - LayoutId( - id: _StackName.header, - child: _header!, - ), - ], - - /// Column footer divider. - if (showColumnFooter) - LayoutId( - id: _StackName.columnFooterDivider, - child: PlutoShadowLine( - axis: Axis.horizontal, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - ), - ), + final bool showColumnRowDivider = + _stateManager.showColumnTitle || _stateManager.showColumnFilter; - /// Footer and divider. - if (_stateManager.showFooter) ...[ - LayoutId( - id: _StackName.footerDivider, - child: PlutoShadowLine( - axis: Axis.horizontal, - color: style.gridBorderColor, - shadow: style.enableGridBorderShadow, - reverse: true, - ), - ), - LayoutId( - id: _StackName.footer, - child: _footer!, + final bool showColumnFooter = _stateManager.showColumnFooter; + + return CustomMultiChildLayout( + key: _stateManager.gridKey, + delegate: PlutoGridLayoutDelegate( + _stateManager, + Directionality.of(context), ), - ], - - /// Loading screen. - if (_stateManager.showLoading) - LayoutId( - id: _StackName.loading, - child: PlutoLoading( - level: _stateManager.loadingLevel, - backgroundColor: style.gridBackgroundColor, - indicatorColor: style.activatedBorderColor, - text: _stateManager.localeText.loadingText, - textStyle: style.cellTextStyle, + children: [ + /// Body columns and rows. + LayoutId( + id: _StackName.bodyRows, + child: PlutoBodyRows(_stateManager), ), - ), - - /// NoRows - if (widget.noRowsWidget != null) - LayoutId( - id: _StackName.noRows, - child: PlutoNoRowsWidget( - stateManager: _stateManager, - child: widget.noRowsWidget!, + LayoutId( + id: _StackName.bodyColumns, + child: PlutoBodyColumns(_stateManager), ), - ), - ], + + /// Body columns footer. + if (showColumnFooter) + LayoutId( + id: _StackName.bodyColumnFooters, + child: PlutoBodyColumnsFooter(stateManager), + ), + + /// Left columns and rows. + if (showLeftFrozen) ...[ + LayoutId( + id: _StackName.leftFrozenColumns, + child: PlutoLeftFrozenColumns(_stateManager), + ), + LayoutId( + id: _StackName.leftFrozenRows, + child: PlutoLeftFrozenRows(_stateManager)), + LayoutId( + id: _StackName.leftFrozenDivider, + child: PlutoShadowLine( + axis: Axis.vertical, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + ), + ), + if (showColumnFooter) + LayoutId( + id: _StackName.leftFrozenColumnFooters, + child: PlutoLeftFrozenColumnsFooter(stateManager), + ), + ], + + /// Right columns and rows. + if (showRightFrozen) ...[ + LayoutId( + id: _StackName.rightFrozenColumns, + child: PlutoRightFrozenColumns(_stateManager), + ), + LayoutId( + id: _StackName.rightFrozenRows, + child: PlutoRightFrozenRows(_stateManager)), + LayoutId( + id: _StackName.rightFrozenDivider, + child: PlutoShadowLine( + axis: Axis.vertical, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + reverse: true, + ), + ), + if (showColumnFooter) + LayoutId( + id: _StackName.rightFrozenColumnFooters, + child: PlutoRightFrozenColumnsFooter(stateManager), + ), + ], + + /// Column and row divider. + if (showColumnRowDivider) + LayoutId( + id: _StackName.columnRowDivider, + child: PlutoShadowLine( + axis: Axis.horizontal, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + ), + ), + + /// Header and divider. + if (_stateManager.showHeader) ...[ + LayoutId( + id: _StackName.headerDivider, + child: PlutoShadowLine( + axis: Axis.horizontal, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + ), + ), + LayoutId( + id: _StackName.header, + child: _header!, + ), + ], + + /// Column footer divider. + if (showColumnFooter) + LayoutId( + id: _StackName.columnFooterDivider, + child: PlutoShadowLine( + axis: Axis.horizontal, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + ), + ), + + /// Footer and divider. + if (_stateManager.showFooter) ...[ + LayoutId( + id: _StackName.footerDivider, + child: PlutoShadowLine( + axis: Axis.horizontal, + color: style.gridBorderColor, + shadow: style.enableGridBorderShadow, + reverse: true, + ), + ), + LayoutId( + id: _StackName.footer, + child: _footer!, + ), + ], + + /// Loading screen. + if (_stateManager.showLoading) + LayoutId( + id: _StackName.loading, + child: PlutoLoading( + level: _stateManager.loadingLevel, + backgroundColor: style.gridBackgroundColor, + indicatorColor: style.activatedBorderColor, + text: _stateManager.localeText.loadingText, + textStyle: style.cellTextStyle, + ), + ), + + /// NoRows + if (widget.noRowsWidget != null) + LayoutId( + id: _StackName.noRows, + child: PlutoNoRowsWidget( + stateManager: _stateManager, + child: widget.noRowsWidget!, + ), + ), + ], + ); + }, ), ), ); @@ -793,10 +800,6 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { @override void performLayout(Size size) { - _performLayoutOnPostFrame(size); - - _stateManager.setLayout(BoxConstraints.tight(size)); - bool isLTR = _stateManager.isLTR; double bodyRowsTopOffset = 0; double bodyRowsBottomOffset = 0; @@ -809,7 +812,7 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { // maximum 40% of the height var s = layoutChild( _StackName.header, - BoxConstraints.loose(Size(size.width, size.height / 100 * 40)), + BoxConstraints.loose(Size(size.width, _safe(size.height / 100 * 40))), ); _stateManager.headerHeight = s.height; @@ -837,7 +840,7 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { // maximum 40% of the height var s = layoutChild( _StackName.footer, - BoxConstraints.loose(Size(size.width, size.height / 100 * 40)), + BoxConstraints.loose(Size(size.width, _safe(size.height / 100 * 40))), ); _stateManager.footerHeight = s.height; @@ -891,7 +894,7 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { BoxConstraints.tight( Size( PlutoGridSettings.gridBorderWidth, - size.height - columnsTopOffset - bodyRowsBottomOffset, + _safe(size.height - columnsTopOffset - bodyRowsBottomOffset), ), ), ); @@ -939,7 +942,7 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { BoxConstraints.tight( Size( PlutoGridSettings.gridBorderWidth, - size.height - columnsTopOffset - bodyRowsBottomOffset, + _safe(size.height - columnsTopOffset - bodyRowsBottomOffset), ), ), ); @@ -964,7 +967,10 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { var s = layoutChild( _StackName.bodyColumns, BoxConstraints.loose( - Size(size.width - bodyLeftOffset - bodyRightOffset, size.height), + Size( + _safe(size.width - bodyLeftOffset - bodyRightOffset), + size.height, + ), ), ); @@ -983,7 +989,10 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { var s = layoutChild( _StackName.bodyColumnFooters, BoxConstraints.loose( - Size(size.width - bodyLeftOffset - bodyRightOffset, size.height), + Size( + _safe(size.width - bodyLeftOffset - bodyRightOffset), + size.height, + ), ), ); @@ -1042,7 +1051,10 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { layoutChild( _StackName.leftFrozenRows, BoxConstraints.loose( - Size(offset, size.height - bodyRowsTopOffset - bodyRowsBottomOffset), + Size( + offset, + _safe(size.height - bodyRowsTopOffset - bodyRowsBottomOffset), + ), ), ); @@ -1061,7 +1073,7 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { layoutChild( _StackName.leftFrozenColumnFooters, BoxConstraints.loose( - Size(offset, size.height - bodyRowsBottomOffset), + Size(offset, _safe(size.height - bodyRowsBottomOffset)), ), ); @@ -1080,7 +1092,10 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { layoutChild( _StackName.rightFrozenRows, BoxConstraints.loose( - Size(offset, size.height - bodyRowsTopOffset - bodyRowsBottomOffset), + Size( + offset, + _safe(size.height - bodyRowsTopOffset - bodyRowsBottomOffset), + ), ), ); @@ -1107,15 +1122,14 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { } if (hasChild(_StackName.bodyRows)) { - double width = size.width - bodyLeftOffset - bodyRightOffset; - double height = size.height - bodyRowsTopOffset - bodyRowsBottomOffset; - - if (width < 0) width = 0; - if (height < 0) height = 0; - layoutChild( _StackName.bodyRows, - BoxConstraints.tight(Size(width, height)), + BoxConstraints.tight(Size( + _safe(size.width - bodyLeftOffset - bodyRightOffset), + _safe( + size.height - bodyRowsTopOffset - bodyRowsBottomOffset, + ), + )), ); positionChild( @@ -1157,11 +1171,14 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { } if (hasChild(_StackName.noRows)) { - var height = size.height - bodyRowsTopOffset - bodyRowsBottomOffset; - layoutChild( _StackName.noRows, - BoxConstraints.loose(Size(size.width, height)), + BoxConstraints.loose( + Size( + size.width, + _safe(size.height - bodyRowsTopOffset - bodyRowsBottomOffset), + ), + ), ); positionChild( @@ -1173,19 +1190,10 @@ class PlutoGridLayoutDelegate extends MultiChildLayoutDelegate { @override bool shouldRelayout(covariant PlutoGridLayoutDelegate oldDelegate) { - final update = _textDirection != oldDelegate._textDirection; - - if (update) _stateManager.performLayoutOnPostFrame(); - - return update; + return true; } - void _performLayoutOnPostFrame(Size size) { - if (_stateManager.showFrozenColumn != - _stateManager.shouldShowFrozenColumns(size.width)) { - _stateManager.performLayoutOnPostFrame(); - } - } + double _safe(double value) => max(0, value); } class _GridContainer extends StatelessWidget { diff --git a/lib/src/ui/miscellaneous/pluto_visibility_layout.dart b/lib/src/ui/miscellaneous/pluto_visibility_layout.dart index a6b7362e5..fdff38c5f 100644 --- a/lib/src/ui/miscellaneous/pluto_visibility_layout.dart +++ b/lib/src/ui/miscellaneous/pluto_visibility_layout.dart @@ -16,7 +16,6 @@ class PlutoVisibilityLayout extends RenderObjectWidget required this.delegate, required this.scrollController, this.initialViewportDimension = 1920, - this.textDirection = TextDirection.ltr, }); @override @@ -30,15 +29,12 @@ class PlutoVisibilityLayout extends RenderObjectWidget /// it is used instead of viewportDimension of scroll. final double initialViewportDimension; - final TextDirection textDirection; - @override PlutoVisibilityLayoutRenderObjectElement createElement() => PlutoVisibilityLayoutRenderObjectElement( widget: this, scrollController: scrollController, initialViewportDimension: initialViewportDimension, - textDirection: textDirection, ); @override @@ -61,7 +57,6 @@ class PlutoVisibilityLayoutRenderObjectElement extends RenderObjectElement required PlutoVisibilityLayout widget, required this.scrollController, this.initialViewportDimension = 1920, - this.textDirection = TextDirection.ltr, }) : assert(!debugChildrenHaveDuplicateKeys(widget, widget.children)), super(widget); @@ -69,8 +64,6 @@ class PlutoVisibilityLayoutRenderObjectElement extends RenderObjectElement final double initialViewportDimension; - TextDirection textDirection; - @override ContainerRenderObjectMixin> get renderObject { @@ -90,11 +83,7 @@ class PlutoVisibilityLayoutRenderObjectElement extends RenderObjectElement final Set _forgottenChildren = HashSet(); Iterable get _widgetChildren { - if (textDirection == TextDirection.ltr) { - return (widget as PlutoVisibilityLayout).children; - } - - return (widget as PlutoVisibilityLayout).children.reversed; + return (widget as PlutoVisibilityLayout).children; } double get _visibleFirst => scrollController.offset; @@ -291,8 +280,6 @@ class PlutoVisibilityLayoutRenderObjectElement extends RenderObjectElement assert(widget == newWidget); - textDirection = newWidget.textDirection; - assert(!debugChildrenHaveDuplicateKeys( widget, _widgetChildren, diff --git a/lib/src/ui/pluto_base_column_group.dart b/lib/src/ui/pluto_base_column_group.dart index 140e47671..84d434976 100644 --- a/lib/src/ui/pluto_base_column_group.dart +++ b/lib/src/ui/pluto_base_column_group.dart @@ -202,14 +202,23 @@ class _ColumnGroup extends StatelessWidget { Widget build(BuildContext context) { if (columnGroup.group.hasFields) { return CustomMultiChildLayout( - delegate: ColumnsLayout(stateManager, columnGroup.columns), + delegate: ColumnsLayout( + stateManager: stateManager, + columns: columnGroup.columns, + textDirection: stateManager.textDirection, + ), children: columnGroup.columns.map(_makeFieldWidget).toList(growable: false), ); } return CustomMultiChildLayout( - delegate: ColumnGroupLayout(stateManager, _separateLinkedGroup, depth), + delegate: ColumnGroupLayout( + stateManager: stateManager, + separateLinkedGroups: _separateLinkedGroup, + depth: depth, + textDirection: stateManager.textDirection, + ), children: _separateLinkedGroup.map(_makeChildWidget).toList(growable: false), ); @@ -217,16 +226,22 @@ class _ColumnGroup extends StatelessWidget { } class ColumnGroupLayout extends MultiChildLayoutDelegate { - PlutoGridStateManager stateManager; + final PlutoGridStateManager stateManager; - List separateLinkedGroups; + final List separateLinkedGroups; - late double totalHeightOfGroup; + final int depth; - int depth; + final TextDirection textDirection; - ColumnGroupLayout(this.stateManager, this.separateLinkedGroups, this.depth) - : super(relayout: stateManager.resizingChangeNotifier); + ColumnGroupLayout({ + required this.stateManager, + required this.separateLinkedGroups, + required this.depth, + required this.textDirection, + }) : super(relayout: stateManager.resizingChangeNotifier); + + late double totalHeightOfGroup; @override Size getSize(BoxConstraints constraints) { @@ -249,9 +264,11 @@ class ColumnGroupLayout extends MultiChildLayoutDelegate { @override void performLayout(Size size) { + final isLTR = textDirection == TextDirection.ltr; + final items = isLTR ? separateLinkedGroups : separateLinkedGroups.reversed; double dx = 0; - for (PlutoColumnGroupPair pair in separateLinkedGroups) { + for (PlutoColumnGroupPair pair in items) { final double width = pair.columns.fold( 0, (previousValue, element) => previousValue + element.width, @@ -276,12 +293,17 @@ class ColumnGroupLayout extends MultiChildLayoutDelegate { } class ColumnsLayout extends MultiChildLayoutDelegate { - PlutoGridStateManager stateManager; + final PlutoGridStateManager stateManager; + + final List columns; - List columns; + final TextDirection textDirection; - ColumnsLayout(this.stateManager, this.columns) - : super(relayout: stateManager.resizingChangeNotifier); + ColumnsLayout({ + required this.stateManager, + required this.columns, + required this.textDirection, + }) : super(relayout: stateManager.resizingChangeNotifier); double totalColumnsHeight = 0; @@ -303,9 +325,11 @@ class ColumnsLayout extends MultiChildLayoutDelegate { @override void performLayout(Size size) { + final isLTR = textDirection == TextDirection.ltr; + final items = isLTR ? columns : columns.reversed; double dx = 0; - for (PlutoColumn col in columns) { + for (PlutoColumn col in items) { final double width = col.width; var boxConstraints = BoxConstraints.tight( diff --git a/lib/src/ui/pluto_base_row.dart b/lib/src/ui/pluto_base_row.dart index 545289408..598098294 100644 --- a/lib/src/ui/pluto_base_row.dart +++ b/lib/src/ui/pluto_base_row.dart @@ -90,10 +90,10 @@ class PlutoBaseRow extends StatelessWidget { delegate: _RowCellsLayoutDelegate( stateManager: stateManager, columns: columns, + textDirection: stateManager.textDirection, ), scrollController: stateManager.scroll.bodyRowsHorizontal!, initialViewportDimension: MediaQuery.of(dragContext).size.width, - textDirection: stateManager.textDirection, children: columns.map(_makeCell).toList(growable: false), ) : CustomMultiChildLayout( @@ -101,6 +101,7 @@ class PlutoBaseRow extends StatelessWidget { delegate: _RowCellsLayoutDelegate( stateManager: stateManager, columns: columns, + textDirection: stateManager.textDirection, ), children: columns.map(_makeCell).toList(growable: false), ), @@ -122,9 +123,12 @@ class _RowCellsLayoutDelegate extends MultiChildLayoutDelegate { final List columns; + final TextDirection textDirection; + _RowCellsLayoutDelegate({ required this.stateManager, required this.columns, + required this.textDirection, }) : super(relayout: stateManager.resizingChangeNotifier); @override @@ -139,9 +143,11 @@ class _RowCellsLayoutDelegate extends MultiChildLayoutDelegate { @override void performLayout(Size size) { + final isLTR = textDirection == TextDirection.ltr; + final items = isLTR ? columns : columns.reversed; double dx = 0; - for (var element in columns) { + for (var element in items) { var width = element.width; if (hasChild(element.field)) { diff --git a/lib/src/ui/pluto_body_columns.dart b/lib/src/ui/pluto_body_columns.dart index ad41ef6cd..417c34a11 100644 --- a/lib/src/ui/pluto_body_columns.dart +++ b/lib/src/ui/pluto_body_columns.dart @@ -72,12 +72,9 @@ class PlutoBodyColumnsState extends PlutoStateWithChange { } List _getColumns() { - final columns = stateManager.showFrozenColumn + return stateManager.showFrozenColumn ? stateManager.bodyColumns : stateManager.columns; - return stateManager.isLTR - ? columns - : columns.reversed.toList(growable: false); } int _getItemCount() { @@ -119,10 +116,10 @@ class PlutoBodyColumnsState extends PlutoStateWithChange { columns: _columns, columnGroups: _columnGroups, frozen: PlutoColumnFrozen.none, + textDirection: stateManager.textDirection, ), scrollController: _scroll, initialViewportDimension: MediaQuery.of(context).size.width, - textDirection: stateManager.textDirection, children: _showColumnGroups == true ? _columnGroups.map(_makeColumnGroup).toList(growable: false) : _columns.map(_makeColumn).toList(growable: false), @@ -140,11 +137,14 @@ class MainColumnLayoutDelegate extends MultiChildLayoutDelegate { final PlutoColumnFrozen frozen; + final TextDirection textDirection; + MainColumnLayoutDelegate({ required this.stateManager, required this.columns, required this.columnGroups, required this.frozen, + required this.textDirection, }) : super(relayout: stateManager.resizingChangeNotifier); double totalColumnsHeight = 0; @@ -173,10 +173,13 @@ class MainColumnLayoutDelegate extends MultiChildLayoutDelegate { @override void performLayout(Size size) { + final isLTR = textDirection == TextDirection.ltr; + if (stateManager.showColumnGroups) { + final items = isLTR ? columnGroups : columnGroups.reversed; double dx = 0; - for (PlutoColumnGroupPair pair in columnGroups) { + for (PlutoColumnGroupPair pair in items) { final double width = pair.columns.fold( 0, (previousValue, element) => previousValue + element.width, @@ -195,9 +198,10 @@ class MainColumnLayoutDelegate extends MultiChildLayoutDelegate { dx += width; } } else { + final items = isLTR ? columns : columns.reversed; double dx = 0; - for (PlutoColumn col in columns) { + for (PlutoColumn col in items) { var width = col.width; if (hasChild(col.field)) { diff --git a/lib/src/ui/pluto_body_columns_footer.dart b/lib/src/ui/pluto_body_columns_footer.dart index f6901c0a4..264747485 100644 --- a/lib/src/ui/pluto_body_columns_footer.dart +++ b/lib/src/ui/pluto_body_columns_footer.dart @@ -52,20 +52,13 @@ class PlutoBodyColumnsFooterState compare: listEquals, ); - _itemCount = update(_itemCount, _getItemCount()); + _itemCount = update(_itemCount, _columns.length); } List _getColumns() { - final columns = stateManager.showFrozenColumn + return stateManager.showFrozenColumn ? stateManager.bodyColumns : stateManager.columns; - return stateManager.isLTR - ? columns - : columns.reversed.toList(growable: false); - } - - int _getItemCount() { - return _columns.length; } PlutoVisibilityLayoutId _makeFooter(PlutoColumn e) { @@ -88,10 +81,10 @@ class PlutoBodyColumnsFooterState delegate: ColumnFooterLayoutDelegate( stateManager: stateManager, columns: _columns, + textDirection: stateManager.textDirection, ), scrollController: _scroll, initialViewportDimension: MediaQuery.of(context).size.width, - textDirection: stateManager.textDirection, children: _columns.map(_makeFooter).toList(growable: false), ), ); @@ -103,9 +96,12 @@ class ColumnFooterLayoutDelegate extends MultiChildLayoutDelegate { final List columns; + final TextDirection textDirection; + ColumnFooterLayoutDelegate({ required this.stateManager, required this.columns, + required this.textDirection, }) : super(relayout: stateManager.resizingChangeNotifier); @override @@ -121,8 +117,11 @@ class ColumnFooterLayoutDelegate extends MultiChildLayoutDelegate { @override void performLayout(Size size) { + final isLTR = textDirection == TextDirection.ltr; + final items = isLTR ? columns : columns.reversed; double dx = 0; - for (PlutoColumn col in columns) { + + for (PlutoColumn col in items) { var width = col.width; if (hasChild(col.field)) { diff --git a/lib/src/ui/pluto_body_rows.dart b/lib/src/ui/pluto_body_rows.dart index d642bcff2..4736fb38b 100644 --- a/lib/src/ui/pluto_body_rows.dart +++ b/lib/src/ui/pluto_body_rows.dart @@ -62,12 +62,9 @@ class PlutoBodyRowsState extends PlutoStateWithChange { } List _getColumns() { - final columns = stateManager.showFrozenColumn == true + return stateManager.showFrozenColumn == true ? stateManager.bodyColumns : stateManager.columns; - return stateManager.isLTR - ? columns - : columns.reversed.toList(growable: false); } @override diff --git a/lib/src/ui/pluto_left_frozen_columns.dart b/lib/src/ui/pluto_left_frozen_columns.dart index 2ad3f8c15..6329ad9c8 100644 --- a/lib/src/ui/pluto_left_frozen_columns.dart +++ b/lib/src/ui/pluto_left_frozen_columns.dart @@ -45,7 +45,7 @@ class PlutoLeftFrozenColumnsState _columns = update>( _columns, - _getColumns(), + stateManager.leftFrozenColumns, compare: listEquals, ); @@ -60,12 +60,6 @@ class PlutoLeftFrozenColumnsState _itemCount = update(_itemCount, _getItemCount()); } - List _getColumns() { - return stateManager.isLTR - ? stateManager.leftFrozenColumns - : stateManager.leftFrozenColumns.reversed.toList(growable: false); - } - int _getItemCount() { return _showColumnGroups == true ? _columnGroups.length : _columns.length; } @@ -99,6 +93,7 @@ class PlutoLeftFrozenColumnsState columns: _columns, columnGroups: _columnGroups, frozen: PlutoColumnFrozen.start, + textDirection: stateManager.textDirection, ), children: _showColumnGroups == true ? _columnGroups.map(_makeColumnGroup).toList(growable: false) diff --git a/lib/src/ui/pluto_left_frozen_columns_footer.dart b/lib/src/ui/pluto_left_frozen_columns_footer.dart index 2b6a32c44..5708813db 100644 --- a/lib/src/ui/pluto_left_frozen_columns_footer.dart +++ b/lib/src/ui/pluto_left_frozen_columns_footer.dart @@ -37,21 +37,11 @@ class PlutoLeftFrozenColumnsFooterState void updateState(PlutoNotifierEvent event) { _columns = update>( _columns, - _getColumns(), + stateManager.leftFrozenColumns, compare: listEquals, ); - _itemCount = update(_itemCount, _getItemCount()); - } - - List _getColumns() { - return stateManager.isLTR - ? stateManager.leftFrozenColumns - : stateManager.leftFrozenColumns.reversed.toList(growable: false); - } - - int _getItemCount() { - return _columns.length; + _itemCount = update(_itemCount, _columns.length); } Widget _makeColumn(PlutoColumn e) { @@ -70,6 +60,7 @@ class PlutoLeftFrozenColumnsFooterState delegate: ColumnFooterLayoutDelegate( stateManager: stateManager, columns: _columns, + textDirection: stateManager.textDirection, ), children: _columns.map(_makeColumn).toList(growable: false), ); diff --git a/lib/src/ui/pluto_left_frozen_rows.dart b/lib/src/ui/pluto_left_frozen_rows.dart index 839a04df8..9cb6a0eb4 100644 --- a/lib/src/ui/pluto_left_frozen_rows.dart +++ b/lib/src/ui/pluto_left_frozen_rows.dart @@ -46,17 +46,11 @@ class PlutoLeftFrozenRowsState void updateState(PlutoNotifierEvent event) { forceUpdate(); - _columns = _getColumns(); + _columns = stateManager.leftFrozenColumns; _rows = stateManager.refRows; } - List _getColumns() { - return stateManager.isLTR - ? stateManager.leftFrozenColumns - : stateManager.leftFrozenColumns.reversed.toList(growable: false); - } - @override Widget build(BuildContext context) { return ListView.builder( diff --git a/lib/src/ui/pluto_right_frozen_columns.dart b/lib/src/ui/pluto_right_frozen_columns.dart index 4a8587edf..e7a37f253 100644 --- a/lib/src/ui/pluto_right_frozen_columns.dart +++ b/lib/src/ui/pluto_right_frozen_columns.dart @@ -45,7 +45,7 @@ class PlutoRightFrozenColumnsState _columns = update>( _columns, - _getColumns(), + stateManager.rightFrozenColumns, compare: listEquals, ); @@ -60,12 +60,6 @@ class PlutoRightFrozenColumnsState _itemCount = update(_itemCount, _getItemCount()); } - List _getColumns() { - return stateManager.isLTR - ? stateManager.rightFrozenColumns - : stateManager.rightFrozenColumns.reversed.toList(growable: false); - } - int _getItemCount() { return _showColumnGroups == true ? _columnGroups.length : _columns.length; } @@ -99,6 +93,7 @@ class PlutoRightFrozenColumnsState columns: _columns, columnGroups: _columnGroups, frozen: PlutoColumnFrozen.end, + textDirection: stateManager.textDirection, ), children: _showColumnGroups == true ? _columnGroups.map(_makeColumnGroup).toList(growable: false) diff --git a/lib/src/ui/pluto_right_frozen_columns_footer.dart b/lib/src/ui/pluto_right_frozen_columns_footer.dart index 12cd75d91..dc5200f59 100644 --- a/lib/src/ui/pluto_right_frozen_columns_footer.dart +++ b/lib/src/ui/pluto_right_frozen_columns_footer.dart @@ -37,21 +37,11 @@ class PlutoRightFrozenColumnsFooterState void updateState(PlutoNotifierEvent event) { _columns = update>( _columns, - _getColumns(), + stateManager.rightFrozenColumns, compare: listEquals, ); - _itemCount = update(_itemCount, _getItemCount()); - } - - List _getColumns() { - return stateManager.isLTR - ? stateManager.rightFrozenColumns - : stateManager.rightFrozenColumns.reversed.toList(growable: false); - } - - int _getItemCount() { - return _columns.length; + _itemCount = update(_itemCount, _columns.length); } Widget _makeColumn(PlutoColumn e) { @@ -70,6 +60,7 @@ class PlutoRightFrozenColumnsFooterState delegate: ColumnFooterLayoutDelegate( stateManager: stateManager, columns: _columns, + textDirection: stateManager.textDirection, ), children: _columns.map(_makeColumn).toList(growable: false), ); diff --git a/lib/src/ui/pluto_right_frozen_rows.dart b/lib/src/ui/pluto_right_frozen_rows.dart index f4e75b411..90244f1af 100644 --- a/lib/src/ui/pluto_right_frozen_rows.dart +++ b/lib/src/ui/pluto_right_frozen_rows.dart @@ -46,17 +46,11 @@ class PlutoRightFrozenRowsState void updateState(PlutoNotifierEvent event) { forceUpdate(); - _columns = _getColumns(); + _columns = stateManager.rightFrozenColumns; _rows = stateManager.refRows; } - List _getColumns() { - return stateManager.isLTR - ? stateManager.rightFrozenColumns - : stateManager.rightFrozenColumns.reversed.toList(growable: false); - } - @override Widget build(BuildContext context) { return ListView.builder( diff --git a/test/mock/shared_mocks.mocks.dart b/test/mock/shared_mocks.mocks.dart index ba07837db..8c07474eb 100644 --- a/test/mock/shared_mocks.mocks.dart +++ b/test/mock/shared_mocks.mocks.dart @@ -2523,18 +2523,18 @@ class MockPlutoGridStateManager extends _i1.Mock returnValueForMissingStub: null, ); @override - void setTextDirection(_i5.TextDirection? textDirection) => super.noSuchMethod( + void notifyChangedShowFrozenColumn() => super.noSuchMethod( Invocation.method( - #setTextDirection, - [textDirection], + #notifyChangedShowFrozenColumn, + [], ), returnValueForMissingStub: null, ); @override - void performLayoutOnPostFrame() => super.noSuchMethod( + void setTextDirection(_i5.TextDirection? textDirection) => super.noSuchMethod( Invocation.method( - #performLayoutOnPostFrame, - [], + #setTextDirection, + [textDirection], ), returnValueForMissingStub: null, ); diff --git a/test/scenario/layout/layout_test.dart b/test/scenario/layout/layout_test.dart new file mode 100644 index 000000000..a58db8753 --- /dev/null +++ b/test/scenario/layout/layout_test.dart @@ -0,0 +1,326 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pluto_grid/pluto_grid.dart'; +import 'package:pluto_grid/src/ui/ui.dart'; + +import '../../helper/column_helper.dart'; +import '../../helper/row_helper.dart'; +import '../../helper/test_helper_util.dart'; + +void main() { + late PlutoGridStateManager stateManager; + late List columns; + late List columnGroups; + late List rows; + + setUp(() { + columns = ColumnHelper.textColumn('column', count: 5); + rows = RowHelper.count(10, columns); + columnGroups = [ + PlutoColumnGroup(title: 'group1', children: [ + PlutoColumnGroup(title: 'group1-1', fields: ['column0', 'column1']), + ]), + ]; + }); + + Future buildGrid({ + required WidgetTester tester, + required List columns, + required List rows, + List? columnGroups, + bool? showColumnFilter, + }) async { + await TestHelperUtil.changeWidth(tester: tester, width: 1200, height: 800); + + await tester.pumpWidget( + MaterialApp( + home: Material( + child: PlutoGrid( + columns: columns, + columnGroups: columnGroups, + rows: rows, + onLoaded: (PlutoGridOnLoadedEvent event) { + stateManager = event.stateManager; + + if (showColumnFilter == true) { + stateManager.setShowColumnFilter(true); + } + }, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + } + + Finder findPlutoBaseColumn(String title) { + return find.ancestor( + of: find.text(title), + matching: find.byType(PlutoBaseColumn), + ); + } + + testWidgets('컬럼 그룹을 숨기면 컬럼 영역의 높이가 변경 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + expect( + tester.getSize(find.byType(PlutoLeftFrozenColumns)).height, + stateManager.columnHeight * 3, + ); + expect( + tester.getSize(find.byType(PlutoBodyColumns)).height, + stateManager.columnHeight * 3, + ); + expect( + tester.getSize(find.byType(PlutoRightFrozenColumns)).height, + stateManager.columnHeight * 3, + ); + + stateManager.setShowColumnGroups(false); + await tester.pumpAndSettle(); + + expect( + tester.getSize(find.byType(PlutoLeftFrozenColumns)).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(find.byType(PlutoBodyColumns)).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(find.byType(PlutoRightFrozenColumns)).height, + stateManager.columnHeight, + ); + }); + + testWidgets('컬럼 그룹을 숨기면 컬럼 그룹이 제거 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + expect(find.text('group1'), findsOneWidget); + expect(find.text('group1-1'), findsOneWidget); + + stateManager.setShowColumnGroups(false); + await tester.pumpAndSettle(); + + expect(find.text('group1'), findsNothing); + expect(find.text('group1-1'), findsNothing); + }); + + testWidgets('컬럼 그룹을 숨기면 컬럼 높이가 변경 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + // group columns + expect( + tester.getSize(findPlutoBaseColumn('column0')).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(findPlutoBaseColumn('column1')).height, + stateManager.columnHeight, + ); + // expanded columns + expect( + tester.getSize(findPlutoBaseColumn('column2')).height, + stateManager.columnHeight * 3, + ); + expect( + tester.getSize(findPlutoBaseColumn('column3')).height, + stateManager.columnHeight * 3, + ); + expect( + tester.getSize(findPlutoBaseColumn('column4')).height, + stateManager.columnHeight * 3, + ); + + stateManager.setShowColumnGroups(false); + await tester.pumpAndSettle(); + + // group columns + expect( + tester.getSize(findPlutoBaseColumn('column0')).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(findPlutoBaseColumn('column1')).height, + stateManager.columnHeight, + ); + // expanded columns + expect( + tester.getSize(findPlutoBaseColumn('column2')).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(findPlutoBaseColumn('column3')).height, + stateManager.columnHeight, + ); + expect( + tester.getSize(findPlutoBaseColumn('column4')).height, + stateManager.columnHeight, + ); + }); + + testWidgets('컬럼 그룹을 숨기면 행 영역의 높이가 변경 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + final changedSize = Size(0, stateManager.columnHeight * 2); + + final leftSize = tester.getSize(find.byType(PlutoLeftFrozenRows)); + final bodySize = tester.getSize(find.byType(PlutoBodyRows)); + final rightSize = tester.getSize(find.byType(PlutoRightFrozenRows)); + + stateManager.setShowColumnGroups(false); + await tester.pumpAndSettle(); + + final afterLeftSize = tester.getSize(find.byType(PlutoLeftFrozenRows)); + final afterBodySize = tester.getSize(find.byType(PlutoBodyRows)); + final afterRightSize = tester.getSize(find.byType(PlutoRightFrozenRows)); + + expect(afterLeftSize.height - changedSize.height, leftSize.height); + expect(afterBodySize.height - changedSize.height, bodySize.height); + expect(afterRightSize.height - changedSize.height, rightSize.height); + + expect(afterLeftSize.width - changedSize.width, leftSize.width); + expect(afterBodySize.width - changedSize.width, bodySize.width); + expect(afterRightSize.width - changedSize.width, rightSize.width); + }); + + testWidgets('화면 크기를 좁게 변경하면 고정 컬럼이 풀려야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + // 시작 고정 컬럼 + expect( + tester.getTopLeft(findPlutoBaseColumn('column2')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column0')).dx), + ); + expect( + tester.getTopLeft(findPlutoBaseColumn('column0')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column1')).dx), + ); + expect( + tester.getTopLeft(findPlutoBaseColumn('column1')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column4')).dx), + ); + // 끝 고정 컬럼 + expect( + tester.getTopLeft(findPlutoBaseColumn('column4')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column3')).dx), + ); + + await TestHelperUtil.changeWidth(tester: tester, width: 500, height: 800); + await tester.pumpAndSettle(); + + expect( + tester.getTopLeft(findPlutoBaseColumn('column0')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column1')).dx), + ); + expect( + tester.getTopLeft(findPlutoBaseColumn('column1')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column2')).dx), + ); + + stateManager.moveScrollByColumn(PlutoMoveDirection.right, 3); + await tester.pumpAndSettle(); + + expect( + tester.getTopLeft(findPlutoBaseColumn('column2')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column3')).dx), + ); + expect( + tester.getTopLeft(findPlutoBaseColumn('column3')).dx, + lessThan(tester.getTopLeft(findPlutoBaseColumn('column4')).dx), + ); + }); + + testWidgets('컬럼을 숨기면 컬럼 영역의 높이가 0이 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + stateManager.setShowColumnTitle(false); + await tester.pumpAndSettle(); + + expect(tester.getSize(find.byType(PlutoLeftFrozenColumns)).height, 0); + expect(tester.getSize(find.byType(PlutoBodyColumns)).height, 0); + expect(tester.getSize(find.byType(PlutoRightFrozenColumns)).height, 0); + }); + + testWidgets('컬럼을 숨기면 행 영역의 높이가 변경 되어야 한다.', (tester) async { + columns[2].frozen = PlutoColumnFrozen.start; + columns[3].frozen = PlutoColumnFrozen.end; + + await buildGrid( + tester: tester, + columns: columns, + rows: rows, + columnGroups: columnGroups, + ); + + final changedSize = Size(0, stateManager.columnHeight * 3); + + final leftSize = tester.getSize(find.byType(PlutoLeftFrozenRows)); + final bodySize = tester.getSize(find.byType(PlutoBodyRows)); + final rightSize = tester.getSize(find.byType(PlutoRightFrozenRows)); + + stateManager.setShowColumnTitle(false); + await tester.pumpAndSettle(); + + final afterLeftSize = tester.getSize(find.byType(PlutoLeftFrozenRows)); + final afterBodySize = tester.getSize(find.byType(PlutoBodyRows)); + final afterRightSize = tester.getSize(find.byType(PlutoRightFrozenRows)); + + expect(afterLeftSize.height - changedSize.height, leftSize.height); + expect(afterBodySize.height - changedSize.height, bodySize.height); + expect(afterRightSize.height - changedSize.height, rightSize.height); + + expect(afterLeftSize.width - changedSize.width, leftSize.width); + expect(afterBodySize.width - changedSize.width, bodySize.width); + expect(afterRightSize.width - changedSize.width, rightSize.width); + }); +} diff --git a/test/src/pluto_grid_test.dart b/test/src/pluto_grid_test.dart index c31df06e7..7d1e976b0 100644 --- a/test/src/pluto_grid_test.dart +++ b/test/src/pluto_grid_test.dart @@ -1345,6 +1345,69 @@ void main() { expect(find.byType(PlutoLoading), findsOneWidget); }); + testWidgets( + 'showLoading 을 rows 레벨로 호출 하면 LinearProgressIndicator 위젯이 나타나야 한다.', + (tester) async { + final columns = ColumnHelper.textColumn('column', count: 10); + final rows = RowHelper.count(10, columns); + + late final PlutoGridStateManager stateManager; + + // when + await tester.pumpWidget( + MaterialApp( + home: Material( + child: PlutoGrid( + columns: columns, + rows: rows, + onLoaded: (PlutoGridOnLoadedEvent event) { + stateManager = event.stateManager; + }, + ), + ), + ), + ); + + stateManager.setShowLoading(true, level: PlutoGridLoadingLevel.rows); + + await tester.pump(); + + expect(find.byType(LinearProgressIndicator), findsOneWidget); + }); + + testWidgets( + 'showLoading 을 rowsBottomCircular 레벨로 호출 하면 CircularProgressIndicator 위젯이 나타나야 한다.', + (tester) async { + final columns = ColumnHelper.textColumn('column', count: 10); + final rows = RowHelper.count(10, columns); + + late final PlutoGridStateManager stateManager; + + // when + await tester.pumpWidget( + MaterialApp( + home: Material( + child: PlutoGrid( + columns: columns, + rows: rows, + onLoaded: (PlutoGridOnLoadedEvent event) { + stateManager = event.stateManager; + }, + ), + ), + ), + ); + + stateManager.setShowLoading( + true, + level: PlutoGridLoadingLevel.rowsBottomCircular, + ); + + await tester.pump(); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }); + testWidgets('showLoading 을 호출 하지 않으면 Loading 위젯이 나타나지 않아야 한다.', (tester) async { final columns = ColumnHelper.textColumn('column', count: 10);