Browse Source

又好了很多。

master
hejl 2 months ago
parent
commit
c210774ee4
  1. 158
      win_text_editor/lib/modules/memory_table/controllers/base_data_source.dart
  2. 176
      win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart
  3. 2
      win_text_editor/lib/modules/memory_table/services/memory_table_service.dart
  4. 69
      win_text_editor/lib/modules/memory_table/widgets/memory_table_left_side.dart

158
win_text_editor/lib/modules/memory_table/controllers/base_data_source.dart

@ -0,0 +1,158 @@
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
abstract class SelectableItem {
bool isSelected = false;
}
abstract class SelectableDataSource<T extends SelectableItem> extends DataGridSource {
SelectableDataSource(this.items) {
_selectionNotifier = ValueNotifier(false);
}
List<T> items;
late final ValueNotifier<bool> _selectionNotifier;
ValueNotifier<bool> get selectionNotifier => _selectionNotifier;
void toggleAllSelection(bool value) {
for (var item in items) {
item.isSelected = value;
}
_updateSelectionState();
notifyListeners();
}
void toggleRowSelection(int index, bool? value) {
items[index].isSelected = value ?? false;
_updateSelectionState();
notifyListeners();
}
void _updateSelectionState() {
final allSelected = items.isNotEmpty && items.every((item) => item.isSelected);
final someSelected = items.isNotEmpty && items.any((item) => item.isSelected);
_selectionNotifier.value = allSelected || someSelected;
}
void updateDataGridSource() {
_updateSelectionState();
notifyListeners();
}
void updateData(List<T> newItems) {
items = newItems;
notifyListeners();
}
}
class Field implements SelectableItem {
Field(this.id, this.name, this.chineseName, this.type, this.remark, [this.isSelected = false]);
final String id;
final String name;
final String chineseName;
final String type;
final String remark;
@override
bool isSelected;
}
//
class Index implements SelectableItem {
Index(this.indexName, this.isPrimary, this.indexFields, this.rule, [this.isSelected = false]);
final String indexName;
final String isPrimary;
final String indexFields;
final String rule;
@override
bool isSelected;
}
class FieldsDataSource extends SelectableDataSource<Field> {
FieldsDataSource(List<Field> fields) : super(fields);
@override
List<DataGridRow> get rows =>
items
.map(
(field) => DataGridRow(
cells: [
DataGridCell<bool>(columnName: 'select', value: field.isSelected),
DataGridCell<String>(columnName: 'id', value: field.id),
DataGridCell<String>(columnName: 'name', value: field.name),
DataGridCell<String>(columnName: 'chineseName', value: field.chineseName),
DataGridCell<String>(columnName: 'type', value: field.type),
DataGridCell<String>(columnName: 'remark', value: field.remark),
],
),
)
.toList();
@override
DataGridRowAdapter buildRow(DataGridRow row) {
final rowIndex = effectiveRows.indexOf(row);
return DataGridRowAdapter(
cells:
row.getCells().map<Widget>((cell) {
if (cell.columnName == 'select') {
return Center(
child: Checkbox(
value: items[rowIndex].isSelected,
onChanged: (value) => toggleRowSelection(rowIndex, value),
),
);
}
return Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(cell.value.toString(), overflow: TextOverflow.ellipsis),
);
}).toList(),
);
}
}
//
class IndexesDataSource extends SelectableDataSource<Index> {
IndexesDataSource(List<Index> indexes) : super(indexes);
@override
List<DataGridRow> get rows =>
items
.map(
(index) => DataGridRow(
cells: [
DataGridCell<bool>(columnName: 'select', value: index.isSelected),
DataGridCell<String>(columnName: 'indexName', value: index.indexName),
DataGridCell<String>(columnName: 'isPrimary', value: index.isPrimary),
DataGridCell<String>(columnName: 'indexFields', value: index.indexFields),
DataGridCell<String>(columnName: 'rule', value: index.rule),
],
),
)
.toList();
@override
DataGridRowAdapter buildRow(DataGridRow row) {
final rowIndex = effectiveRows.indexOf(row);
return DataGridRowAdapter(
cells:
row.getCells().map<Widget>((cell) {
if (cell.columnName == 'select') {
return Center(
child: Checkbox(
value: items[rowIndex].isSelected,
onChanged: (value) => toggleRowSelection(rowIndex, value),
),
);
}
return Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(cell.value.toString(), overflow: TextOverflow.ellipsis),
);
}).toList(),
);
}
}

176
win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart

@ -1,183 +1,9 @@
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/modules/memory_table/controllers/base_data_source.dart';
import 'package:win_text_editor/modules/memory_table/services/memory_table_service.dart'; import 'package:win_text_editor/modules/memory_table/services/memory_table_service.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart';
//
class Field {
Field(this.id, this.name, this.chineseName, this.type, this.remark, [this.isSelected = false]);
final String id; //
final String name; //
final String chineseName; //
final String type; //
final String remark; //
bool isSelected;
}
//
class Index {
Index(this.indexName, this.isPrimary, this.indexFields, this.rule, [this.isSelected = false]);
final String indexName; //
final String isPrimary; //
final String indexFields; //
final String rule; //
bool isSelected;
}
//
class FieldsDataSource extends DataGridSource {
FieldsDataSource(this.fields) {
_selectionNotifier = ValueNotifier<bool>(false);
}
List<Field> fields;
late ValueNotifier<bool> _selectionNotifier;
ValueNotifier<bool> get selectionNotifier => _selectionNotifier;
void toggleAllSelection(bool value) {
for (var field in fields) {
field.isSelected = value;
}
_selectionNotifier.value = !_selectionNotifier.value; // Trigger rebuild
notifyListeners();
}
void updateData(List<Field> newFields) {
fields = newFields;
notifyListeners(); // DataGrid更新
}
@override
List<DataGridRow> get rows =>
fields
.map(
(field) => DataGridRow(
cells: [
DataGridCell<bool>(columnName: 'select', value: field.isSelected),
DataGridCell<String>(columnName: 'id', value: field.id),
DataGridCell<String>(columnName: 'name', value: field.name),
DataGridCell<String>(columnName: 'chineseName', value: field.chineseName),
DataGridCell<String>(columnName: 'type', value: field.type),
DataGridCell<String>(columnName: 'remark', value: field.remark),
],
),
)
.toList();
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
final int rowIndex = effectiveRows.indexOf(row);
return DataGridRowAdapter(
cells:
row.getCells().map<Widget>((dataGridCell) {
if (dataGridCell.columnName == 'select') {
return Center(
child: Checkbox(
value: fields[rowIndex].isSelected,
onChanged: (value) {
toggleRowSelection(rowIndex, value);
},
),
);
}
return Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(dataGridCell.value.toString(), overflow: TextOverflow.ellipsis),
);
}).toList(),
);
}
void toggleRowSelection(int index, bool? value) {
fields[index].isSelected = value ?? false;
notifyListeners();
}
}
//
class IndexesDataSource extends DataGridSource {
IndexesDataSource(this.indexes) {
_selectionNotifier = ValueNotifier<bool>(false);
}
List<Index> indexes;
late ValueNotifier<bool> _selectionNotifier;
get selectionNotifier => _selectionNotifier;
void toggleAllSelection(bool value) {
for (var index in indexes) {
index.isSelected = value;
}
_selectionNotifier.value = !_selectionNotifier.value; // Trigger rebuild
notifyListeners();
}
void toggleRowSelection(int index, bool? value) {
indexes[index].isSelected = value ?? false;
notifyListeners();
}
void updateData(List<Index> newIndexes) {
indexes = newIndexes;
notifyListeners(); // DataGrid更新
}
@override
List<DataGridRow> get rows =>
indexes
.map(
(index) => DataGridRow(
cells: [
DataGridCell<bool>(columnName: 'select', value: index.isSelected),
DataGridCell<String>(columnName: 'indexName', value: index.indexName),
DataGridCell<String>(columnName: 'isPrimary', value: index.isPrimary),
DataGridCell<String>(columnName: 'indexFields', value: index.indexFields),
DataGridCell<String>(columnName: 'rule', value: index.rule),
],
),
)
.toList();
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
final int rowIndex = effectiveRows.indexOf(row);
return DataGridRowAdapter(
cells:
row.getCells().map<Widget>((dataGridCell) {
if (dataGridCell.columnName == 'select') {
return Center(
child: Checkbox(
value: indexes[rowIndex].isSelected,
onChanged: (value) {
toggleRowSelection(rowIndex, value);
},
),
);
}
return Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(dataGridCell.value.toString(), overflow: TextOverflow.ellipsis),
);
}).toList(),
);
}
bool _getSelectedValue(DataGridRow row) {
final int rowIndex = rows.indexOf(row);
if (rowIndex == -1) {
return false;
}
return indexes[rowIndex].isSelected;
}
}
class MemoryTableController extends BaseContentController { class MemoryTableController extends BaseContentController {
String? _errorMessage; String? _errorMessage;
String tableName = ""; String tableName = "";

2
win_text_editor/lib/modules/memory_table/services/memory_table_service.dart

@ -1,7 +1,7 @@
// memory_table_service.dart // memory_table_service.dart
import 'dart:io'; import 'dart:io';
import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart'; import 'package:win_text_editor/modules/memory_table/controllers/base_data_source.dart';
import 'package:xml/xml.dart' as xml; import 'package:xml/xml.dart' as xml;
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/framework/controllers/logger.dart';

69
win_text_editor/lib/modules/memory_table/widgets/memory_table_left_side.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:win_text_editor/modules/memory_table/controllers/base_data_source.dart';
import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart'; import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart';
class MemoryTableLeftSide extends StatelessWidget { class MemoryTableLeftSide extends StatelessWidget {
@ -55,14 +56,9 @@ class MemoryTableLeftSide extends StatelessWidget {
GridColumn( GridColumn(
columnName: 'select', columnName: 'select',
label: ValueListenableBuilder<bool>( label: ValueListenableBuilder<bool>(
valueListenable: (fieldsSource).selectionNotifier, valueListenable: fieldsSource.selectionNotifier,
builder: (context, _, __) { builder:
return _buildCheckboxHeader( (context, _, __) => _buildCheckboxHeader(context, fieldsSource),
context,
fieldsSource,
fieldsSource.fields.length,
);
},
), ),
width: 60, width: 60,
), ),
@ -95,10 +91,10 @@ class MemoryTableLeftSide extends StatelessWidget {
onCellTap: (details) { onCellTap: (details) {
if (details.column.columnName == 'select') { if (details.column.columnName == 'select') {
final rowIndex = details.rowColumnIndex.rowIndex - 1; final rowIndex = details.rowColumnIndex.rowIndex - 1;
if (rowIndex >= 0 && rowIndex < fieldsSource.fields.length) { if (rowIndex >= 0 && rowIndex < fieldsSource.items.length) {
fieldsSource.toggleRowSelection( fieldsSource.toggleRowSelection(
rowIndex, rowIndex,
!fieldsSource.fields[rowIndex].isSelected, !fieldsSource.items[rowIndex].isSelected,
); );
} }
} }
@ -114,10 +110,16 @@ class MemoryTableLeftSide extends StatelessWidget {
); );
} }
Widget _buildCheckboxHeader(BuildContext context, FieldsDataSource dataSource, int rowCount) { Widget _buildCheckboxHeader<T extends SelectableItem>(
final allSelected = rowCount > 0 && dataSource.fields.every((item) => item.isSelected); BuildContext context,
SelectableDataSource<T> dataSource,
) {
final allSelected =
dataSource.items.isNotEmpty && dataSource.items.every((item) => item.isSelected);
final someSelected = final someSelected =
rowCount > 0 && dataSource.fields.any((item) => item.isSelected) && !allSelected; dataSource.items.isNotEmpty &&
dataSource.items.any((item) => item.isSelected) &&
!allSelected;
return Container( return Container(
alignment: Alignment.center, alignment: Alignment.center,
@ -125,9 +127,7 @@ class MemoryTableLeftSide extends StatelessWidget {
child: Checkbox( child: Checkbox(
value: allSelected, value: allSelected,
tristate: someSelected, tristate: someSelected,
onChanged: (value) { onChanged: (value) => dataSource.toggleAllSelection(value ?? false),
dataSource.toggleAllSelection(value ?? false);
},
), ),
); );
} }
@ -155,14 +155,9 @@ class MemoryTableLeftSide extends StatelessWidget {
GridColumn( GridColumn(
columnName: 'select', columnName: 'select',
label: ValueListenableBuilder<bool>( label: ValueListenableBuilder<bool>(
valueListenable: (indexesSource).selectionNotifier, valueListenable: indexesSource.selectionNotifier,
builder: (context, _, __) { builder:
return _buildCheckboxHeaderForIndexes( (context, _, __) => _buildCheckboxHeader(context, indexesSource),
context,
indexesSource,
indexesSource.indexes.length,
);
},
), ),
width: 60, width: 60,
), ),
@ -190,10 +185,10 @@ class MemoryTableLeftSide extends StatelessWidget {
onCellTap: (details) { onCellTap: (details) {
if (details.column.columnName == 'select') { if (details.column.columnName == 'select') {
final rowIndex = details.rowColumnIndex.rowIndex - 1; final rowIndex = details.rowColumnIndex.rowIndex - 1;
if (rowIndex >= 0 && rowIndex < indexesSource.indexes.length) { if (rowIndex >= 0 && rowIndex < indexesSource.items.length) {
indexesSource.toggleRowSelection( indexesSource.toggleRowSelection(
rowIndex, rowIndex,
!indexesSource.indexes[rowIndex].isSelected, !indexesSource.items[rowIndex].isSelected,
); );
} }
} }
@ -209,28 +204,6 @@ class MemoryTableLeftSide extends StatelessWidget {
); );
} }
Widget _buildCheckboxHeaderForIndexes(
BuildContext context,
IndexesDataSource dataSource,
int rowCount,
) {
final allSelected = rowCount > 0 && dataSource.indexes.every((item) => item.isSelected);
final someSelected =
rowCount > 0 && dataSource.indexes.any((item) => item.isSelected) && !allSelected;
return Container(
alignment: Alignment.center,
color: Colors.grey[200],
child: Checkbox(
value: allSelected,
tristate: someSelected,
onChanged: (value) {
dataSource.toggleAllSelection(value ?? false);
},
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(

Loading…
Cancel
Save