feat: add CopyFunc to provider generator; add local solution provider; update dde data table style.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
class ProviderModel {
|
class ProviderModel {
|
||||||
const ProviderModel();
|
const ProviderModel({this.copyable = false});
|
||||||
|
|
||||||
|
final bool copyable;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProviderModelProp {
|
class ProviderModelProp {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ class ProviderGenerator extends GeneratorForAnnotation<ProviderModel> {
|
|||||||
_genImports(className, needImports),
|
_genImports(className, needImports),
|
||||||
_genClassDefine(element.displayName),
|
_genClassDefine(element.displayName),
|
||||||
_genNamedConstructors(element.constructors, element.displayName),
|
_genNamedConstructors(element.constructors, element.displayName),
|
||||||
|
_genCopyFunc(element.displayName, fields, annotation.read('copyable').boolValue),
|
||||||
_genSetPropsFunc(fields),
|
_genSetPropsFunc(fields),
|
||||||
].whereNotNull();
|
].whereNotNull();
|
||||||
}
|
}
|
||||||
@@ -71,6 +72,17 @@ String? _genNamedConstructors(List<ConstructorElement> constructors, String disp
|
|||||||
return _constructors.length > 0 ? _constructors.join('\n') : null;
|
return _constructors.length > 0 ? _constructors.join('\n') : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? _genCopyFunc(String displayName, List<AnnotationField> fields, bool copyable) {
|
||||||
|
if (!copyable) return null;
|
||||||
|
return '''
|
||||||
|
void copyFrom(${displayName} other) {
|
||||||
|
bool changed = false;
|
||||||
|
${fields.map((f) => 'if (other.${f.name}.diff(this.${f.name})) {this.${f.name} = other.${f.name}; changed = true; }').join('\n')}
|
||||||
|
if (changed) notifyListeners();
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
String _genSetPropsFunc(List<AnnotationField> fields) => '''
|
String _genSetPropsFunc(List<AnnotationField> fields) => '''
|
||||||
void setProps({
|
void setProps({
|
||||||
${fields.map((f) => '${f.type.endsWith('?') ? '' : 'required '}${f.type} ${f.name},').join('\n')}
|
${fields.map((f) => '${f.type.endsWith('?') ? '' : 'required '}${f.type} ${f.name},').join('\n')}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export 'local_solutions_web.dart' if (dart.library.io) 'local_solutions_linux.dart';
|
||||||
|
|
||||||
|
import 'package:dde_gesture_manager/models/solution.dart';
|
||||||
|
|
||||||
|
abstract class LocalSolutionEntry {
|
||||||
|
Solution solution;
|
||||||
|
DateTime lastModifyTime;
|
||||||
|
String path;
|
||||||
|
|
||||||
|
LocalSolutionEntry({
|
||||||
|
required this.path,
|
||||||
|
required this.solution,
|
||||||
|
required this.lastModifyTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LocalSolutionsInterface<T extends LocalSolutionEntry> {
|
||||||
|
Future<List<T>> get solutionEntries;
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
|
||||||
|
import 'package:dde_gesture_manager/extensions.dart';
|
||||||
|
import 'package:dde_gesture_manager/models/solution.dart';
|
||||||
|
import 'package:path/path.dart' show join;
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
|
import 'local_solutions.dart';
|
||||||
|
|
||||||
|
export 'local_solutions.dart';
|
||||||
|
|
||||||
|
@ProviderModel()
|
||||||
|
class LocalSolutions implements LocalSolutionsInterface<LocalSolutionEntryLinux> {
|
||||||
|
LocalSolutions() {
|
||||||
|
solutionEntries.then((value) => solutions = value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<LocalSolutionEntryLinux>> get solutionEntries async {
|
||||||
|
var _supportDirectory = await getApplicationSupportDirectory();
|
||||||
|
var directory = Directory(join(_supportDirectory.path, 'solutions'));
|
||||||
|
if (!directory.existsSync()) directory.createSync();
|
||||||
|
directory.path.sout();
|
||||||
|
return directory
|
||||||
|
.list()
|
||||||
|
.map<LocalSolutionEntryLinux?>((f) {
|
||||||
|
LocalSolutionEntryLinux? entry;
|
||||||
|
try {
|
||||||
|
var content = File(f.path).readAsStringSync();
|
||||||
|
entry = LocalSolutionEntryLinux(
|
||||||
|
path: f.path, solution: Solution.parse(content), lastModifyTime: f.statSync().modified);
|
||||||
|
} catch (e) {
|
||||||
|
e.sout();
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
})
|
||||||
|
.where((e) => e != null)
|
||||||
|
.cast<LocalSolutionEntryLinux>()
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProviderModelProp()
|
||||||
|
List<LocalSolutionEntry>? solutions;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalSolutionEntryLinux implements LocalSolutionEntry {
|
||||||
|
@override
|
||||||
|
String path;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Solution solution;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime lastModifyTime;
|
||||||
|
|
||||||
|
LocalSolutionEntryLinux({
|
||||||
|
required this.path,
|
||||||
|
required this.solution,
|
||||||
|
required this.lastModifyTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
save() {
|
||||||
|
// TODO: implement save
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export 'local_solutions_web.provider.dart' if (dart.library.io) 'local_solutions_linux.provider.dart';
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
|
||||||
|
import 'package:dde_gesture_manager/models/solution.dart';
|
||||||
|
import 'package:dde_gesture_manager/extensions.dart';
|
||||||
|
import 'dart:html';
|
||||||
|
|
||||||
|
import 'local_solutions.dart';
|
||||||
|
export 'local_solutions.dart';
|
||||||
|
|
||||||
|
@ProviderModel()
|
||||||
|
class LocalSolutions implements LocalSolutionsInterface<LocalSolutionEntryWeb> {
|
||||||
|
LocalSolutions() {
|
||||||
|
solutionEntries.then((value) => solutions = value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<LocalSolutionEntryWeb>> get solutionEntries async {
|
||||||
|
return window.localStorage.keys
|
||||||
|
.map<LocalSolutionEntryWeb?>((key) {
|
||||||
|
if (key.startsWith('solutions.')) {
|
||||||
|
LocalSolutionEntryWeb? entry;
|
||||||
|
try {
|
||||||
|
var content = window.localStorage[key] ?? '';
|
||||||
|
var solutionJson = json.decode(content);
|
||||||
|
entry = LocalSolutionEntryWeb(
|
||||||
|
path: key,
|
||||||
|
solution: Solution.parse(solutionJson),
|
||||||
|
lastModifyTime: DateTime.parse(solutionJson['modified_at']),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
e.sout();
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.where((e) => e != null)
|
||||||
|
.cast<LocalSolutionEntryWeb>()
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ProviderModelProp()
|
||||||
|
List<LocalSolutionEntry>? solutions;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalSolutionEntryWeb implements LocalSolutionEntry {
|
||||||
|
@override
|
||||||
|
String path;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Solution solution;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime lastModifyTime;
|
||||||
|
|
||||||
|
LocalSolutionEntryWeb({
|
||||||
|
required this.path,
|
||||||
|
required this.solution,
|
||||||
|
required this.lastModifyTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
save() {
|
||||||
|
// TODO: implement save
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
|
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
|
||||||
import 'package:dde_gesture_manager/utils/helper.dart';
|
import 'package:dde_gesture_manager/utils/helper.dart';
|
||||||
|
|
||||||
@ProviderModel()
|
@ProviderModel(copyable: true)
|
||||||
class Solution {
|
class Solution {
|
||||||
@ProviderModelProp()
|
@ProviderModelProp()
|
||||||
String? name;
|
String? name;
|
||||||
@@ -45,7 +45,7 @@ enum GestureType {
|
|||||||
shortcut,
|
shortcut,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ProviderModel()
|
@ProviderModel(copyable: true)
|
||||||
class GestureProp {
|
class GestureProp {
|
||||||
@ProviderModelProp()
|
@ProviderModelProp()
|
||||||
Gesture? gesture;
|
Gesture? gesture;
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ class GestureEditor extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: Text('${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(gesture.gesture)}').tr(),
|
child: Text('${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(gesture.gesture)}').tr(),
|
||||||
),
|
),
|
||||||
Text('${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(gesture.direction)}').tr(),
|
Center(
|
||||||
|
child: Text('${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(gesture.direction)}')
|
||||||
|
.tr()),
|
||||||
Center(
|
Center(
|
||||||
child: Text('${gesture.fingers}'),
|
child: Text('${gesture.fingers}'),
|
||||||
),
|
),
|
||||||
@@ -126,15 +128,15 @@ class GestureEditor extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
dataRowColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
|
dataRowColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
|
||||||
if (states.contains(MaterialState.hovered)) return Colors.grey;
|
if (states.contains(MaterialState.hovered)) return context.t.dialogBackgroundColor;
|
||||||
if (states.contains(MaterialState.selected)) return Colors.green;
|
if (states.contains(MaterialState.selected)) return Colors.blueAccent;
|
||||||
return null;
|
return null;
|
||||||
}),
|
}),
|
||||||
columns: [
|
columns: [
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_gesture.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_gesture.tr()), center: true),
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_direction.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_direction.tr()), center: true),
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_fingers.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_fingers.tr()), center: true),
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_type.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_type.tr()), center: true),
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_command.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_command.tr())),
|
||||||
DDataColumn(label: Text(LocaleKeys.gesture_editor_remark.tr())),
|
DDataColumn(label: Text(LocaleKeys.gesture_editor_remark.tr())),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:dde_gesture_manager/extensions.dart';
|
import 'package:dde_gesture_manager/extensions.dart';
|
||||||
|
import 'package:dde_gesture_manager/models/local_solutions_provider.dart';
|
||||||
import 'package:dde_gesture_manager/models/solution.provider.dart';
|
import 'package:dde_gesture_manager/models/solution.provider.dart';
|
||||||
import 'package:dde_gesture_manager/pages/content.dart';
|
import 'package:dde_gesture_manager/pages/content.dart';
|
||||||
import 'package:dde_gesture_manager/pages/footer.dart';
|
import 'package:dde_gesture_manager/pages/footer.dart';
|
||||||
@@ -65,6 +66,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}
|
}
|
||||||
''')),
|
''')),
|
||||||
ChangeNotifierProvider(create: (context) => GesturePropProvider.empty()),
|
ChangeNotifierProvider(create: (context) => GesturePropProvider.empty()),
|
||||||
|
ChangeNotifierProvider(create: (context) => LocalSolutionsProvider(),lazy: false),
|
||||||
],
|
],
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
|||||||
@@ -1,20 +1,45 @@
|
|||||||
import 'package:dde_gesture_manager/constants/constants.dart';
|
import 'package:dde_gesture_manager/constants/constants.dart';
|
||||||
import 'package:dde_gesture_manager/extensions.dart';
|
import 'package:dde_gesture_manager/extensions.dart';
|
||||||
import 'package:dde_gesture_manager/models/content_layout.provider.dart';
|
import 'package:dde_gesture_manager/models/content_layout.provider.dart';
|
||||||
|
import 'package:dde_gesture_manager/models/local_solutions_provider.dart';
|
||||||
|
import 'package:dde_gesture_manager/models/solution.provider.dart';
|
||||||
import 'package:dde_gesture_manager/widgets/dde_button.dart';
|
import 'package:dde_gesture_manager/widgets/dde_button.dart';
|
||||||
import 'package:flutter/animation.dart';
|
import 'package:flutter/animation.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
|
||||||
class LocalManager extends StatelessWidget {
|
class LocalManager extends StatefulWidget {
|
||||||
const LocalManager({
|
const LocalManager({
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LocalManager> createState() => _LocalManagerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LocalManagerState extends State<LocalManager> {
|
||||||
|
late ScrollController _scrollController;
|
||||||
|
int? _hoveringIndex;
|
||||||
|
int? _selectedIndex;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_scrollController = ScrollController();
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _getItemBackgroundColor(int index) {
|
||||||
|
Color _color = index % 2 == 0 ? context.t.scaffoldBackgroundColor : context.t.backgroundColor;
|
||||||
|
if (index == _hoveringIndex) _color = context.t.scaffoldBackgroundColor;
|
||||||
|
if (index == _selectedIndex) _color = Colors.blueAccent;
|
||||||
|
return _color;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var isOpen = context.watch<ContentLayoutProvider>().localManagerOpened == true;
|
var isOpen = context.watch<ContentLayoutProvider>().localManagerOpened == true;
|
||||||
|
var localSolutions = context.watch<LocalSolutionsProvider>().solutions ?? [];
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: mediumDuration,
|
duration: mediumDuration,
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@@ -57,6 +82,57 @@ class LocalManager extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: _scrollController,
|
||||||
|
itemBuilder: (context, index) => GestureDetector(
|
||||||
|
onDoubleTap: () {
|
||||||
|
context.read<SolutionProvider>().copyFrom(localSolutions[index].solution);
|
||||||
|
setState(() {
|
||||||
|
_selectedIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
onEnter: (_) {
|
||||||
|
setState(() {
|
||||||
|
_hoveringIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: _getItemBackgroundColor(index),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 12.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(localSolutions[index].solution.name ?? ''),
|
||||||
|
Text('456'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
itemCount: localSolutions.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 150,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class DDataColumn {
|
|||||||
this.tooltip,
|
this.tooltip,
|
||||||
this.numeric = false,
|
this.numeric = false,
|
||||||
this.onSort,
|
this.onSort,
|
||||||
|
this.center = false,
|
||||||
}) : assert(label != null);
|
}) : assert(label != null);
|
||||||
|
|
||||||
/// The column heading.
|
/// The column heading.
|
||||||
@@ -66,6 +67,8 @@ class DDataColumn {
|
|||||||
final DataColumnSortCallback? onSort;
|
final DataColumnSortCallback? onSort;
|
||||||
|
|
||||||
bool get _debugInteractive => onSort != null;
|
bool get _debugInteractive => onSort != null;
|
||||||
|
|
||||||
|
final bool center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Row configuration and cell data for a [DataTable].
|
/// Row configuration and cell data for a [DataTable].
|
||||||
@@ -735,68 +738,6 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
widget.rows.any((DDataRow row) => row._debugInteractive);
|
widget.rows.any((DDataRow row) => row._debugInteractive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleSelectAll(bool? checked, bool someChecked) {
|
|
||||||
// If some checkboxes are checked, all checkboxes are selected. Otherwise,
|
|
||||||
// use the new checked value but default to false if it's null.
|
|
||||||
final bool effectiveChecked = someChecked || (checked ?? false);
|
|
||||||
if (widget.onSelectAll != null) {
|
|
||||||
widget.onSelectAll!(effectiveChecked);
|
|
||||||
} else {
|
|
||||||
for (final DDataRow row in widget.rows) {
|
|
||||||
if (row.onSelectChanged != null && row.selected != effectiveChecked) row.onSelectChanged!(effectiveChecked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCheckbox({
|
|
||||||
required BuildContext context,
|
|
||||||
required bool? checked,
|
|
||||||
required VoidCallback? onRowTap,
|
|
||||||
required ValueChanged<bool?>? onCheckboxChanged,
|
|
||||||
required MaterialStateProperty<Color?>? overlayColor,
|
|
||||||
required bool tristate,
|
|
||||||
}) {
|
|
||||||
final ThemeData themeData = Theme.of(context);
|
|
||||||
final double effectiveHorizontalMargin =
|
|
||||||
widget.horizontalMargin ?? themeData.dataTableTheme.horizontalMargin ?? DDataTable._horizontalMargin;
|
|
||||||
final double effectiveCheckboxHorizontalMarginStart = widget.checkboxHorizontalMargin ??
|
|
||||||
themeData.dataTableTheme.checkboxHorizontalMargin ??
|
|
||||||
effectiveHorizontalMargin;
|
|
||||||
final double effectiveCheckboxHorizontalMarginEnd = widget.checkboxHorizontalMargin ??
|
|
||||||
themeData.dataTableTheme.checkboxHorizontalMargin ??
|
|
||||||
effectiveHorizontalMargin / 2.0;
|
|
||||||
Widget contents = Semantics(
|
|
||||||
container: true,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsetsDirectional.only(
|
|
||||||
start: effectiveCheckboxHorizontalMarginStart,
|
|
||||||
end: effectiveCheckboxHorizontalMarginEnd,
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Checkbox(
|
|
||||||
// TODO(per): Remove when Checkbox has theme, https://github.com/flutter/flutter/issues/53420.
|
|
||||||
activeColor: themeData.colorScheme.primary,
|
|
||||||
checkColor: themeData.colorScheme.onPrimary,
|
|
||||||
value: checked,
|
|
||||||
onChanged: onCheckboxChanged,
|
|
||||||
tristate: tristate,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (onRowTap != null) {
|
|
||||||
contents = TableRowInkWell(
|
|
||||||
onTap: onRowTap,
|
|
||||||
overlayColor: overlayColor,
|
|
||||||
child: contents,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return TableCell(
|
|
||||||
verticalAlignment: TableCellVerticalAlignment.fill,
|
|
||||||
child: contents,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildHeadingCell({
|
Widget _buildHeadingCell({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required EdgeInsetsGeometry padding,
|
required EdgeInsetsGeometry padding,
|
||||||
@@ -806,11 +747,13 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
required VoidCallback? onSort,
|
required VoidCallback? onSort,
|
||||||
required bool sorted,
|
required bool sorted,
|
||||||
required bool ascending,
|
required bool ascending,
|
||||||
|
required bool center,
|
||||||
required MaterialStateProperty<Color?>? overlayColor,
|
required MaterialStateProperty<Color?>? overlayColor,
|
||||||
}) {
|
}) {
|
||||||
final ThemeData themeData = Theme.of(context);
|
final ThemeData themeData = Theme.of(context);
|
||||||
label = Row(
|
label = Row(
|
||||||
textDirection: numeric ? TextDirection.rtl : null,
|
textDirection: numeric ? TextDirection.rtl : null,
|
||||||
|
mainAxisAlignment: center ? MainAxisAlignment.spaceAround : MainAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
label,
|
label,
|
||||||
if (onSort != null) ...<Widget>[
|
if (onSort != null) ...<Widget>[
|
||||||
@@ -935,24 +878,13 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
);
|
);
|
||||||
final bool anyRowSelectable = widget.rows.any((DDataRow row) => row.onSelectChanged != null);
|
final bool anyRowSelectable = widget.rows.any((DDataRow row) => row.onSelectChanged != null);
|
||||||
final bool displayCheckboxColumn = widget.showCheckboxColumn && anyRowSelectable;
|
final bool displayCheckboxColumn = widget.showCheckboxColumn && anyRowSelectable;
|
||||||
final Iterable<DDataRow> rowsWithCheckbox =
|
|
||||||
displayCheckboxColumn ? widget.rows.where((DDataRow row) => row.onSelectChanged != null) : <DDataRow>[];
|
|
||||||
final Iterable<DDataRow> rowsChecked = rowsWithCheckbox.where((DDataRow row) => row.selected);
|
|
||||||
final bool allChecked = displayCheckboxColumn && rowsChecked.length == rowsWithCheckbox.length;
|
|
||||||
final bool anyChecked = displayCheckboxColumn && rowsChecked.isNotEmpty;
|
|
||||||
final bool someChecked = anyChecked && !allChecked;
|
|
||||||
final double effectiveHorizontalMargin =
|
final double effectiveHorizontalMargin =
|
||||||
widget.horizontalMargin ?? theme.dataTableTheme.horizontalMargin ?? DDataTable._horizontalMargin;
|
widget.horizontalMargin ?? theme.dataTableTheme.horizontalMargin ?? DDataTable._horizontalMargin;
|
||||||
final double effectiveCheckboxHorizontalMarginStart =
|
|
||||||
widget.checkboxHorizontalMargin ?? theme.dataTableTheme.checkboxHorizontalMargin ?? effectiveHorizontalMargin;
|
|
||||||
final double effectiveCheckboxHorizontalMarginEnd = widget.checkboxHorizontalMargin ??
|
|
||||||
theme.dataTableTheme.checkboxHorizontalMargin ??
|
|
||||||
effectiveHorizontalMargin / 2.0;
|
|
||||||
final double effectiveColumnSpacing =
|
final double effectiveColumnSpacing =
|
||||||
widget.columnSpacing ?? theme.dataTableTheme.columnSpacing ?? DDataTable._columnSpacing;
|
widget.columnSpacing ?? theme.dataTableTheme.columnSpacing ?? DDataTable._columnSpacing;
|
||||||
|
|
||||||
final List<TableColumnWidth> tableColumns = List<TableColumnWidth>.filled(
|
final List<TableColumnWidth> tableColumns = List<TableColumnWidth>.filled(
|
||||||
widget.columns.length + (displayCheckboxColumn ? 1 : 0), const _NullTableColumnWidth());
|
widget.columns.length, const _NullTableColumnWidth());
|
||||||
final List<TableRow> tableRows = List<TableRow>.generate(
|
final List<TableRow> tableRows = List<TableRow>.generate(
|
||||||
widget.rows.length + 1, // the +1 is for the header row
|
widget.rows.length + 1, // the +1 is for the header row
|
||||||
(int index) {
|
(int index) {
|
||||||
@@ -989,34 +921,6 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
int rowIndex;
|
int rowIndex;
|
||||||
|
|
||||||
int displayColumnIndex = 0;
|
int displayColumnIndex = 0;
|
||||||
if (displayCheckboxColumn) {
|
|
||||||
tableColumns[0] = FixedColumnWidth(0);
|
|
||||||
tableRows[0].children![0] = RectGetter.defaultKey(child: Container());
|
|
||||||
// tableColumns[0] = FixedColumnWidth(
|
|
||||||
// effectiveCheckboxHorizontalMarginStart + Checkbox.width + effectiveCheckboxHorizontalMarginEnd);
|
|
||||||
// tableRows[0].children![0] = _buildCheckbox(
|
|
||||||
// context: context,
|
|
||||||
// checked: someChecked ? null : allChecked,
|
|
||||||
// onRowTap: null,
|
|
||||||
// onCheckboxChanged: (bool? checked) => _handleSelectAll(checked, someChecked),
|
|
||||||
// overlayColor: null,
|
|
||||||
// tristate: true,
|
|
||||||
// );
|
|
||||||
rowIndex = 1;
|
|
||||||
for (final DDataRow row in widget.rows) {
|
|
||||||
// tableRows[rowIndex].children![0] = _buildCheckbox(
|
|
||||||
// context: context,
|
|
||||||
// checked: row.selected,
|
|
||||||
// onRowTap: row.onSelectChanged == null ? null : () => row.onSelectChanged?.call(!row.selected),
|
|
||||||
// onCheckboxChanged: row.onSelectChanged,
|
|
||||||
// overlayColor: row.color ?? effectiveDataRowColor,
|
|
||||||
// tristate: false,
|
|
||||||
// );
|
|
||||||
tableRows[rowIndex].children![0] = Container();
|
|
||||||
rowIndex += 1;
|
|
||||||
}
|
|
||||||
displayColumnIndex += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int dataColumnIndex = 0; dataColumnIndex < widget.columns.length; dataColumnIndex += 1) {
|
for (int dataColumnIndex = 0; dataColumnIndex < widget.columns.length; dataColumnIndex += 1) {
|
||||||
final DDataColumn column = widget.columns[dataColumnIndex];
|
final DDataColumn column = widget.columns[dataColumnIndex];
|
||||||
@@ -1060,6 +964,7 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
sorted: dataColumnIndex == widget.sortColumnIndex,
|
sorted: dataColumnIndex == widget.sortColumnIndex,
|
||||||
ascending: widget.sortAscending,
|
ascending: widget.sortAscending,
|
||||||
overlayColor: effectiveHeadingRowColor,
|
overlayColor: effectiveHeadingRowColor,
|
||||||
|
center: column.center,
|
||||||
);
|
);
|
||||||
rowIndex = 1;
|
rowIndex = 1;
|
||||||
for (final DDataRow row in widget.rows) {
|
for (final DDataRow row in widget.rows) {
|
||||||
@@ -1125,11 +1030,11 @@ class _DDataTableState extends State<DDataTable> {
|
|||||||
fit: StackFit.passthrough,
|
fit: StackFit.passthrough,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: _headersRect?.first.height ?? 0),
|
padding: EdgeInsets.only(top: _headersRect?.last.height ?? 0),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(0, -(_headersRect?.first.height ?? 0)),
|
offset: Offset(0, -(_headersRect?.last.height ?? 0)),
|
||||||
child: Table(
|
child: Table(
|
||||||
columnWidths: tableColumns.asMap(),
|
columnWidths: tableColumns.asMap(),
|
||||||
children: tableRows,
|
children: tableRows,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ dependencies:
|
|||||||
easy_localization: ^3.0.0
|
easy_localization: ^3.0.0
|
||||||
glass_kit: ^2.0.1
|
glass_kit: ^2.0.1
|
||||||
rect_getter: ^1.0.0
|
rect_getter: ^1.0.0
|
||||||
|
path_provider: ^2.0.5
|
||||||
xdg_directories_web:
|
xdg_directories_web:
|
||||||
path: 3rd_party/xdg_directories_web
|
path: 3rd_party/xdg_directories_web
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user