board_cell.dart 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import 'package:app_flowy/plugins/grid/application/prelude.dart';
  2. import 'package:flutter/material.dart';
  3. abstract class FocusableBoardCell {
  4. set becomeFocus(bool isFocus);
  5. }
  6. class EditableCellNotifier {
  7. final ValueNotifier<bool> isCellEditing;
  8. EditableCellNotifier({bool isEditing = false})
  9. : isCellEditing = ValueNotifier(isEditing);
  10. void dispose() {
  11. isCellEditing.dispose();
  12. }
  13. }
  14. class EditableRowNotifier {
  15. final Map<EditableCellId, EditableCellNotifier> _cells = {};
  16. final ValueNotifier<bool> isEditing;
  17. EditableRowNotifier({required bool isEditing})
  18. : isEditing = ValueNotifier(isEditing);
  19. void bindCell(
  20. GridCellIdentifier cellIdentifier,
  21. EditableCellNotifier notifier,
  22. ) {
  23. assert(
  24. _cells.values.isEmpty,
  25. 'Only one cell can receive the notification',
  26. );
  27. final id = EditableCellId.from(cellIdentifier);
  28. _cells[id]?.dispose();
  29. notifier.isCellEditing.addListener(() {
  30. isEditing.value = notifier.isCellEditing.value;
  31. });
  32. _cells[EditableCellId.from(cellIdentifier)] = notifier;
  33. }
  34. void becomeFirstResponder() {
  35. if (_cells.values.isEmpty) return;
  36. assert(
  37. _cells.values.length == 1,
  38. 'Only one cell can receive the notification',
  39. );
  40. _cells.values.first.isCellEditing.value = true;
  41. }
  42. void resignFirstResponder() {
  43. if (_cells.values.isEmpty) return;
  44. assert(
  45. _cells.values.length == 1,
  46. 'Only one cell can receive the notification',
  47. );
  48. _cells.values.first.isCellEditing.value = false;
  49. }
  50. void unbind() {
  51. for (final notifier in _cells.values) {
  52. notifier.dispose();
  53. }
  54. _cells.clear();
  55. }
  56. void dispose() {
  57. for (final notifier in _cells.values) {
  58. notifier.dispose();
  59. }
  60. _cells.clear();
  61. }
  62. }
  63. abstract class EditableCell {
  64. // Each cell notifier will be bind to the [EditableRowNotifier], which enable
  65. // the row notifier receive its cells event. For example: begin editing the
  66. // cell or end editing the cell.
  67. //
  68. EditableCellNotifier? get editableNotifier;
  69. }
  70. class EditableCellId {
  71. String fieldId;
  72. String rowId;
  73. EditableCellId(this.rowId, this.fieldId);
  74. factory EditableCellId.from(GridCellIdentifier cellIdentifier) =>
  75. EditableCellId(
  76. cellIdentifier.rowId,
  77. cellIdentifier.fieldId,
  78. );
  79. }