@@ -2,12 +2,7 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_service/cell_serv
22import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show FieldType;
33import 'package:flutter/services.dart' ;
44import 'package:flutter/widgets.dart' ;
5- import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart' ;
6- import 'package:flowy_infra/theme.dart' ;
75import 'package:flutter/material.dart' ;
8- import 'package:provider/provider.dart' ;
9- import 'package:app_flowy/workspace/presentation/plugins/grid/src/layout/sizes.dart' ;
10- import 'package:styled_widget/styled_widget.dart' ;
116import 'cell_accessory.dart' ;
127import 'cell_shortcuts.dart' ;
138import 'checkbox_cell.dart' ;
@@ -50,11 +45,30 @@ class BlankCell extends StatelessWidget {
5045 }
5146}
5247
53- abstract class GridCellWidget extends StatefulWidget implements CellAccessory , CellFocustable , CellShortcuts {
54- GridCellWidget ({Key ? key}) : super (key: key);
48+ abstract class CellEditable {
49+ GridCellFocusListener get beginFocus;
50+
51+ ValueNotifier <bool > get onCellFocus;
52+
53+ ValueNotifier <bool > get onCellEditing;
54+ }
55+
56+ abstract class GridCellWidget extends StatefulWidget implements CellAccessory , CellEditable , CellShortcuts {
57+ GridCellWidget ({Key ? key}) : super (key: key) {
58+ onCellEditing.addListener (() {
59+ onCellFocus.value = onCellEditing.value;
60+ });
61+ }
62+
63+ @override
64+ final ValueNotifier <bool > onCellFocus = ValueNotifier <bool >(false );
65+
66+ // When the cell is focused, we assume that the accessory alse be hovered.
67+ @override
68+ ValueNotifier <bool > get onAccessoryHover => onCellFocus;
5569
5670 @override
57- final ValueNotifier <bool > isFocus = ValueNotifier <bool >(false );
71+ final ValueNotifier <bool > onCellEditing = ValueNotifier <bool >(false );
5872
5973 @override
6074 List <GridCellAccessory > Function (GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null ;
@@ -137,9 +151,9 @@ abstract class GridFocusNodeCellState<T extends GridCellWidget> extends GridCell
137151 }
138152
139153 void _listenOnFocusNodeChanged () {
140- widget.isFocus .value = focusNode.hasFocus;
154+ widget.onCellEditing .value = focusNode.hasFocus;
141155 focusNode.setListener (() {
142- widget.isFocus .value = focusNode.hasFocus;
156+ widget.onCellEditing .value = focusNode.hasFocus;
143157 focusChanged ();
144158 });
145159 }
@@ -190,121 +204,3 @@ class SingleListenrFocusNode extends FocusNode {
190204 }
191205 }
192206}
193-
194- class CellStateNotifier extends ChangeNotifier {
195- bool _isFocus = false ;
196- bool _onEnter = false ;
197-
198- set isFocus (bool value) {
199- if (_isFocus != value) {
200- _isFocus = value;
201- notifyListeners ();
202- }
203- }
204-
205- set onEnter (bool value) {
206- if (_onEnter != value) {
207- _onEnter = value;
208- notifyListeners ();
209- }
210- }
211-
212- bool get isFocus => _isFocus;
213-
214- bool get onEnter => _onEnter;
215- }
216-
217- abstract class CellFocustable {
218- GridCellFocusListener get beginFocus;
219- }
220-
221- class CellContainer extends StatelessWidget {
222- final GridCellWidget child;
223- final AccessoryBuilder ? accessoryBuilder;
224- final double width;
225- final RegionStateNotifier rowStateNotifier;
226- const CellContainer ({
227- Key ? key,
228- required this .child,
229- required this .width,
230- required this .rowStateNotifier,
231- this .accessoryBuilder,
232- }) : super (key: key);
233-
234- @override
235- Widget build (BuildContext context) {
236- return ChangeNotifierProxyProvider <RegionStateNotifier , CellStateNotifier >(
237- create: (_) => CellStateNotifier (),
238- update: (_, row, cell) => cell! ..onEnter = row.onEnter,
239- child: Selector <CellStateNotifier , bool >(
240- selector: (context, notifier) => notifier.isFocus,
241- builder: (context, isFocus, _) {
242- Widget container = Center (child: GridCellShortcuts (child: child));
243- child.isFocus.addListener (() {
244- Provider .of <CellStateNotifier >(context, listen: false ).isFocus = child.isFocus.value;
245- });
246-
247- if (accessoryBuilder != null ) {
248- final buildContext = GridCellAccessoryBuildContext (anchorContext: context);
249- final accessories = accessoryBuilder !(buildContext);
250- if (accessories.isNotEmpty) {
251- container = CellEnterRegion (child: container, accessories: accessories);
252- }
253- }
254-
255- return GestureDetector (
256- behavior: HitTestBehavior .translucent,
257- onTap: () => child.beginFocus.notify (),
258- child: Container (
259- constraints: BoxConstraints (maxWidth: width, minHeight: 46 ),
260- decoration: _makeBoxDecoration (context, isFocus),
261- padding: GridSize .cellContentInsets,
262- child: container,
263- ),
264- );
265- },
266- ),
267- );
268- }
269-
270- BoxDecoration _makeBoxDecoration (BuildContext context, bool isFocus) {
271- final theme = context.watch <AppTheme >();
272- if (isFocus) {
273- final borderSide = BorderSide (color: theme.main1, width: 1.0 );
274- return BoxDecoration (border: Border .fromBorderSide (borderSide));
275- } else {
276- final borderSide = BorderSide (color: theme.shader5, width: 1.0 );
277- return BoxDecoration (border: Border (right: borderSide, bottom: borderSide));
278- }
279- }
280- }
281-
282- class CellEnterRegion extends StatelessWidget {
283- final Widget child;
284- final List <GridCellAccessory > accessories;
285- const CellEnterRegion ({required this .child, required this .accessories, Key ? key}) : super (key: key);
286-
287- @override
288- Widget build (BuildContext context) {
289- return Selector <CellStateNotifier , bool >(
290- selector: (context, notifier) => notifier.onEnter,
291- builder: (context, onEnter, _) {
292- List <Widget > children = [child];
293- if (onEnter) {
294- children.add (AccessoryContainer (accessories: accessories).positioned (right: 0 ));
295- }
296-
297- return MouseRegion (
298- cursor: SystemMouseCursors .click,
299- onEnter: (p) => Provider .of <CellStateNotifier >(context, listen: false ).onEnter = true ,
300- onExit: (p) => Provider .of <CellStateNotifier >(context, listen: false ).onEnter = false ,
301- child: Stack (
302- alignment: AlignmentDirectional .center,
303- fit: StackFit .expand,
304- children: children,
305- ),
306- );
307- },
308- );
309- }
310- }
0 commit comments