diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index 8ebc70352b..4d62dc9eb2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -44,7 +44,16 @@ class BlankCell extends StatelessWidget { abstract class GridCellWidget extends HoverWidget { @override final ValueNotifier onFocus = ValueNotifier(false); + + final GridCellRequestFocusNotifier requestFocus = GridCellRequestFocusNotifier(); + GridCellWidget({Key? key}) : super(key: key); } +class GridCellRequestFocusNotifier extends ChangeNotifier { + void notify() { + notifyListeners(); + } +} + abstract class GridCellStyle {} diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart index 17c1e87710..89f3700a0d 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_container.dart @@ -1,3 +1,4 @@ +import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -31,17 +32,20 @@ class CellContainer extends StatelessWidget { final GridCellWidget child; final Widget? expander; final double width; + final RegionStateNotifier rowStateNotifier; const CellContainer({ Key? key, required this.child, required this.width, + required this.rowStateNotifier, this.expander, }) : super(key: key); @override Widget build(BuildContext context) { - return ChangeNotifierProvider( + return ChangeNotifierProxyProvider( create: (_) => CellStateNotifier(), + update: (_, row, cell) => cell!..onEnter = row.onEnter, child: Selector( selector: (context, notifier) => notifier.isFocus, builder: (context, isFocus, _) { @@ -54,11 +58,15 @@ class CellContainer extends StatelessWidget { container = _CellEnterRegion(child: container, expander: expander!); } - return Container( - constraints: BoxConstraints(maxWidth: width), - decoration: _makeBoxDecoration(context, isFocus), - padding: GridSize.cellContentInsets, - child: container, + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => child.requestFocus.notify(), + child: Container( + constraints: BoxConstraints(maxWidth: width), + decoration: _makeBoxDecoration(context, isFocus), + padding: GridSize.cellContentInsets, + child: container, + ), ); }, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index 80d5c70f8d..99fcd4a26f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -24,6 +24,7 @@ class _CheckboxCellState extends State { void initState() { final cellContext = widget.cellContextBuilder.build(); _cellBloc = getIt(param1: cellContext)..add(const CheckboxCellEvent.initial()); + _listenCellRequestFocus(); super.initState(); } @@ -48,9 +49,21 @@ class _CheckboxCellState extends State { ); } + @override + void didUpdateWidget(covariant CheckboxCell oldWidget) { + _listenCellRequestFocus(); + super.didUpdateWidget(oldWidget); + } + @override Future dispose() async { _cellBloc.close(); super.dispose(); } + + void _listenCellRequestFocus() { + widget.requestFocus.addListener(() { + _cellBloc.add(const CheckboxCellEvent.select()); + }); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index 6d66ab7c3e..9901790fa5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -23,6 +23,7 @@ class _NumberCellState extends State { late NumberCellBloc _cellBloc; late TextEditingController _controller; late FocusNode _focusNode; + VoidCallback? _focusListener; Timer? _delayOperation; @override @@ -40,6 +41,7 @@ class _NumberCellState extends State { @override Widget build(BuildContext context) { + _listenCellRequestFocus(context); return BlocProvider.value( value: _cellBloc, child: BlocConsumer( @@ -68,6 +70,9 @@ class _NumberCellState extends State { @override Future dispose() async { + if (_focusListener != null) { + widget.requestFocus.removeListener(_focusListener!); + } _delayOperation?.cancel(); _cellBloc.close(); _focusNode.dispose(); @@ -89,4 +94,19 @@ class _NumberCellState extends State { }); } } + + void _listenCellRequestFocus(BuildContext context) { + if (_focusListener != null) { + widget.requestFocus.removeListener(_focusListener!); + } + + focusListener() { + if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) { + FocusScope.of(context).requestFocus(_focusNode); + } + } + + _focusListener = focusListener; + widget.requestFocus.addListener(focusListener); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart index a9d3d13532..822dc69fb9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/text_cell.dart @@ -36,7 +36,7 @@ class _GridTextCellState extends State { late TextCellBloc _cellBloc; late TextEditingController _controller; late FocusNode _focusNode; - + VoidCallback? _focusListener; Timer? _delayOperation; @override @@ -50,11 +50,14 @@ class _GridTextCellState extends State { widget.onFocus.value = _focusNode.hasFocus; focusChanged(); }); + super.initState(); } @override Widget build(BuildContext context) { + _listenCellRequestFocus(context); + return BlocProvider.value( value: _cellBloc, child: BlocConsumer( @@ -84,8 +87,26 @@ class _GridTextCellState extends State { ); } + void _listenCellRequestFocus(BuildContext context) { + if (_focusListener != null) { + widget.requestFocus.removeListener(_focusListener!); + } + + focusListener() { + if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) { + FocusScope.of(context).requestFocus(_focusNode); + } + } + + _focusListener = focusListener; + widget.requestFocus.addListener(focusListener); + } + @override Future dispose() async { + if (_focusListener != null) { + widget.requestFocus.removeListener(_focusListener!); + } _delayOperation?.cancel(); _cellBloc.close(); _focusNode.dispose(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 62cdc5c53f..eb744af7b2 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -88,7 +88,7 @@ class _RowLeading extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer<_RegionStateNotifier>( + return Consumer( builder: (context, state, _) { return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null); }, @@ -164,13 +164,13 @@ class _RowCells extends StatelessWidget { return Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, - children: _makeCells(state.cellDataMap), + children: _makeCells(context, state.cellDataMap), ); }, ); } - List _makeCells(GridCellMap gridCellMap) { + List _makeCells(BuildContext context, GridCellMap gridCellMap) { return gridCellMap.values.map( (gridCell) { Widget? expander; @@ -181,6 +181,7 @@ class _RowCells extends StatelessWidget { return CellContainer( width: gridCell.field.width.toDouble(), child: buildGridCellWidget(gridCell, cellCache), + rowStateNotifier: Provider.of(context, listen: false), expander: expander, ); }, @@ -188,7 +189,7 @@ class _RowCells extends StatelessWidget { } } -class _RegionStateNotifier extends ChangeNotifier { +class RegionStateNotifier extends ChangeNotifier { bool _onEnter = false; set onEnter(bool value) { @@ -226,11 +227,11 @@ class _RowEnterRegion extends StatefulWidget { } class _RowEnterRegionState extends State<_RowEnterRegion> { - late _RegionStateNotifier _rowStateNotifier; + late RegionStateNotifier _rowStateNotifier; @override void initState() { - _rowStateNotifier = _RegionStateNotifier(); + _rowStateNotifier = RegionStateNotifier(); super.initState(); }