diff --git a/app/lib/models/local_schemes.dart b/app/lib/models/local_schemes.dart index 9108a32..9a79be2 100644 --- a/app/lib/models/local_schemes.dart +++ b/app/lib/models/local_schemes.dart @@ -1,5 +1,7 @@ import 'package:dde_gesture_manager/models/scheme.dart'; +import 'local_schemes_provider.dart'; + export 'local_schemes_web.dart' if (dart.library.io) 'local_schemes_linux.dart'; abstract class LocalSchemeEntry implements Comparable { @@ -20,7 +22,7 @@ abstract class LocalSchemeEntry implements Comparable { /// max value of DateTime ![Time Values and Time Range](https://262.ecma-international.org/11.0/#sec-time-values-and-time-range) this.lastModifyTime = DateTime.fromMillisecondsSinceEpoch(8640000000000000); - save(); + save(LocalSchemesProvider provider); } abstract class LocalSchemesInterface { diff --git a/app/lib/models/local_schemes_linux.dart b/app/lib/models/local_schemes_linux.dart index e118cb0..e74d98e 100644 --- a/app/lib/models/local_schemes_linux.dart +++ b/app/lib/models/local_schemes_linux.dart @@ -8,6 +8,7 @@ import 'package:path/path.dart' show join; import 'package:path_provider/path_provider.dart'; import 'local_schemes.dart'; +import 'local_schemes_provider.dart'; export 'local_schemes.dart'; @@ -68,9 +69,11 @@ class LocalSchemeEntryLinux implements LocalSchemeEntry { this.lastModifyTime = DateTime.fromMillisecondsSinceEpoch(8640000000000000); @override - save() { + save(LocalSchemesProvider provider) { var file = File(path); - file.writeAsStringSync(json.encode(scheme)); + file.writeAsStringSync(JsonEncoder.withIndent(' ' * 4).convert(scheme)); + provider.schemes!.firstWhere((ele) => ele.scheme.id == scheme.id).lastModifyTime = DateTime.now(); + provider.setProps(schemes: [...provider.schemes!]..sort()); } @override diff --git a/app/lib/models/local_schemes_web.dart b/app/lib/models/local_schemes_web.dart index e252c36..582141c 100644 --- a/app/lib/models/local_schemes_web.dart +++ b/app/lib/models/local_schemes_web.dart @@ -3,6 +3,7 @@ import 'dart:html'; import 'package:dde_gesture_manager/builder/provider_annotation.dart'; import 'package:dde_gesture_manager/extensions.dart'; +import 'package:dde_gesture_manager/models/local_schemes_provider.dart'; import 'package:dde_gesture_manager/models/scheme.dart'; import 'local_schemes.dart'; @@ -68,7 +69,7 @@ class LocalSchemeEntryWeb implements LocalSchemeEntry { this.lastModifyTime = DateTime.fromMillisecondsSinceEpoch(8640000000000000); @override - save() { + save(LocalSchemesProvider provider) { // TODO: implement save throw UnimplementedError(); } diff --git a/app/lib/models/scheme.dart b/app/lib/models/scheme.dart index 8f9d42c..d6cfde6 100644 --- a/app/lib/models/scheme.dart +++ b/app/lib/models/scheme.dart @@ -117,6 +117,9 @@ class Scheme { String? id; @ProviderModelProp() + bool? readOnly; + + @ProviderModelProp() String? name; @ProviderModelProp() @@ -129,6 +132,7 @@ class Scheme { if (scheme is String) scheme = json.decode(scheme); assert(scheme is Map); id = scheme['id'] ?? Uuid().v1(); + readOnly = scheme['readOnly'] ?? false; name = scheme['name']; description = scheme['desc']; gestures = (scheme['gestures'] as List? ?? []).map((ele) => GestureProp.parse(ele)).toList()..sort(); @@ -136,6 +140,7 @@ class Scheme { Scheme.systemDefault() { this.id = Uuid.NAMESPACE_NIL; + this.readOnly = true; this.name = LocaleKeys.local_manager_default_scheme_label.tr(); this.description = LocaleKeys.local_manager_default_scheme_description.tr(); this.gestures = []; @@ -157,6 +162,7 @@ class Scheme { Map toJson() => { 'id': id, + 'readOnly': readOnly, 'name': name, 'desc': description, 'gestures': gestures, diff --git a/app/lib/pages/gesture_editor.dart b/app/lib/pages/gesture_editor.dart index 21fb172..57a350b 100644 --- a/app/lib/pages/gesture_editor.dart +++ b/app/lib/pages/gesture_editor.dart @@ -126,27 +126,32 @@ class GestureEditor extends StatelessWidget { controller: horizontalCtrl, child: ConstrainedBox( constraints: BoxConstraints(minWidth: constraints.maxWidth), - child: DDataTable( - showBottomBorder: true, - headingRowHeight: _headingRowHeight, - showCheckboxColumn: true, - headerBackgroundColor: context.t.dialogBackgroundColor, - verticalScrollController: verticalCtrl, - dataRowColor: MaterialStateProperty.resolveWith((Set states) { - if (states.contains(MaterialState.hovered)) return context.t.dialogBackgroundColor; - if (states.contains(MaterialState.selected)) - return context.read().currentActiveColor; - return null; - }), - columns: [ - DDataColumn(label: Text(LocaleKeys.gesture_editor_fingers.tr()), center: true), - DDataColumn(label: Text(LocaleKeys.gesture_editor_gesture.tr()), center: true), - DDataColumn(label: Text(LocaleKeys.gesture_editor_direction.tr()), center: true), - DDataColumn(label: Text(LocaleKeys.gesture_editor_type.tr()), center: true), - DDataColumn(label: Text(LocaleKeys.gesture_editor_command.tr())), - DDataColumn(label: Text(LocaleKeys.gesture_editor_remark.tr())), - ], - rows: _buildDataRows(schemeProvider.gestures, context), + child: IgnorePointer( + ignoring: schemeProvider.readOnly ?? false, + child: DDataTable( + showBottomBorder: true, + headingRowHeight: _headingRowHeight, + showCheckboxColumn: true, + headerBackgroundColor: context.t.dialogBackgroundColor, + verticalScrollController: verticalCtrl, + dataRowColor: + MaterialStateProperty.resolveWith((Set states) { + if (states.contains(MaterialState.hovered)) + return context.t.dialogBackgroundColor; + if (states.contains(MaterialState.selected)) + return context.read().currentActiveColor; + return null; + }), + columns: [ + DDataColumn(label: Text(LocaleKeys.gesture_editor_fingers.tr()), center: true), + DDataColumn(label: Text(LocaleKeys.gesture_editor_gesture.tr()), center: true), + DDataColumn(label: Text(LocaleKeys.gesture_editor_direction.tr()), center: true), + DDataColumn(label: Text(LocaleKeys.gesture_editor_type.tr()), center: true), + DDataColumn(label: Text(LocaleKeys.gesture_editor_command.tr())), + DDataColumn(label: Text(LocaleKeys.gesture_editor_remark.tr())), + ], + rows: _buildDataRows(schemeProvider.gestures, context), + ), ), ), ), @@ -164,18 +169,23 @@ class GestureEditor extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ DButton.add( - enabled: !gesturePropProvider.editMode! && !schemeTree.fullFiled, + enabled: !(schemeProvider.readOnly ?? false) && + !gesturePropProvider.editMode! && + !schemeTree.fullFiled, onTap: () { var schemeProvider = context.read(); - context.read().setProps( - gestures: [ - ...?schemeProvider.gestures, - H.getNextAvailableGestureProp(schemeProvider.buildSchemeTree())!, - ]..sort()); + var newGestures = [ + ...?schemeProvider.gestures, + H.getNextAvailableGestureProp(schemeProvider.buildSchemeTree())!, + ]..sort(); + context.read().setProps(gestures: newGestures); + saveGesturesToLocal(context, schemeProvider, newGestures); }, ), DButton.delete( - enabled: gesturePropProvider != GestureProp.empty() && !gesturePropProvider.editMode!, + enabled: !(schemeProvider.readOnly ?? false) && + gesturePropProvider != GestureProp.empty() && + !gesturePropProvider.editMode!, onTap: () { var schemeProvider = context.read(); var index = schemeProvider.gestures?.indexWhere((e) => e.id == gesturePropProvider.id); @@ -187,10 +197,13 @@ class GestureEditor extends StatelessWidget { gesturePropProvider.copyFrom( newGestures[(index ?? 0) > newGestures.length - 1 ? newGestures.length - 1 : index ?? 0] ..editMode = false); + saveGesturesToLocal(context, schemeProvider, newGestures); }, ), DButton.duplicate( - enabled: gesturePropProvider != GestureProp.empty() && !gesturePropProvider.editMode!, + enabled: !(schemeProvider.readOnly ?? false) && + gesturePropProvider != GestureProp.empty() && + !gesturePropProvider.editMode!, onTap: () { var schemeProvider = context.read(); context.read().copyFrom( @@ -200,7 +213,8 @@ class GestureEditor extends StatelessWidget { }, ), DButton.paste( - enabled: copiedGesturePropProvider != CopiedGesturePropProvider.empty() && + enabled: !(schemeProvider.readOnly ?? false) && + copiedGesturePropProvider != CopiedGesturePropProvider.empty() && !gesturePropProvider.editMode! && !schemeTree.fullFiled, onTap: () { @@ -221,11 +235,12 @@ class GestureEditor extends StatelessWidget { newGestureProp.remark = copiedGesturePropProvider.remark; } newGestureProp.id = Uuid().v1(); - context.read().setProps( - gestures: [ - ...?schemeProvider.gestures, - newGestureProp, - ]..sort()); + var newGestures = [ + ...?schemeProvider.gestures, + newGestureProp, + ]..sort(); + context.read().setProps(gestures: newGestures); + saveGesturesToLocal(context, schemeProvider, newGestures); }, ), ] @@ -258,6 +273,7 @@ class GestureEditor extends StatelessWidget { Expanded( child: DTextField( initText: schemeProvider.name, + readOnly: schemeProvider.readOnly ?? false, onComplete: (val) { val = val.trim(); schemeProvider.setProps(name: val); @@ -271,11 +287,7 @@ class GestureEditor extends StatelessWidget { var localSchemeEntry = localSchemesProvider.schemes! .firstWhere((ele) => ele.scheme.id == schemeProvider.id); localSchemeEntry.scheme.name = val; - localSchemeEntry.save(); - localSchemesProvider.schemeEntries.then((value) { - localSchemesProvider - .setProps(schemes: [localSchemesProvider.schemes!.first, ...value..sort()]); - }); + localSchemeEntry.save(localSchemesProvider); }, ), ), @@ -314,9 +326,11 @@ List _buildDataRows(List? gestures, BuildContext context) var newGestures = List.of(schemeProvider.gestures!); var index = newGestures.indexWhere((element) => element == prop); newGestures[index].copyFrom(prop); + newGestures.sort(); context.read().setProps( - gestures: newGestures..sort(), + gestures: newGestures, ); + saveGesturesToLocal(context, schemeProvider, newGestures); }; provider.copyFrom( gesture..editMode = true, @@ -328,6 +342,13 @@ List _buildDataRows(List? gestures, BuildContext context) ); }).toList(); +void saveGesturesToLocal(BuildContext context, SchemeProvider schemeProvider, List newGestures) { + var localSchemesProvider = context.read(); + var localSchemeEntry = localSchemesProvider.schemes!.firstWhere((ele) => ele.scheme.id == schemeProvider.id); + localSchemeEntry.scheme.gestures = newGestures; + localSchemeEntry.save(localSchemesProvider); +} + List _buildRowCellsEditing(BuildContext context) { var gesture = context.read(); var schemeTree = context.read().buildSchemeTree(); diff --git a/app/lib/pages/home.dart b/app/lib/pages/home.dart index f425962..8efcf89 100644 --- a/app/lib/pages/home.dart +++ b/app/lib/pages/home.dart @@ -18,55 +18,9 @@ class _HomePageState extends State { return Scaffold( body: MultiProvider( providers: [ - ChangeNotifierProvider(create: (context) => SchemeProvider.parse(''' - { - "name": "test", - "desc": "some desc", - "gestures": [ - { - "gesture": "swipe", - "direction": "down", - "fingers": 3, - "type": "shortcut", - "command": "Control_L+w", - "remark": "close current page." - }, - { - "gesture": "swipe", - "direction": "up", - "fingers": 3, - "type": "shortcut", - "command": "Control_L+Alt_L+t", - "remark": "reopen last closed page." - }, - { - "gesture": "pinch", - "direction": "in", - "fingers": 4, - "type": "shortcut", - "command": "Control_L+Alt_L+f", - "remark": "search files." - }, - { - "gesture": "tap", - "fingers": 4, - "type": "built_in", - "command": "handle4FingersTap", - "remark": "handle4FingersTap." - }, - { - "gesture": "swipe", - "direction": "down", - "fingers": 5, - "type": "commandline", - "command": "dbus-send --type=method_call --dest=com.deepin.dde.Launcher /com/deepin/dde/Launcher com.deepin.dde.Launcher.Toggle", - "remark": "toggle launcher." - } - ] - } - ''')), + ChangeNotifierProvider(create: (context) => SchemeProvider.systemDefault()), ChangeNotifierProvider(create: (context) => GesturePropProvider.empty()), - ChangeNotifierProvider(create: (context) => LocalSchemesProvider(),lazy: false), + ChangeNotifierProvider(create: (context) => LocalSchemesProvider(), lazy: false), ], child: Column( mainAxisSize: MainAxisSize.max, diff --git a/app/lib/widgets/dde_button.dart b/app/lib/widgets/dde_button.dart index 38bcbc0..7aad5ad 100644 --- a/app/lib/widgets/dde_button.dart +++ b/app/lib/widgets/dde_button.dart @@ -143,7 +143,7 @@ class _DButtonState extends State { begin: Alignment.topCenter, end: Alignment.bottomCenter, ), - borderColor: _hovering + borderColor: _hovering && widget.onTap != null ? (widget.activeBorderColor ?? context.watch().currentActiveColor) : Color(0xff565656), borderWidth: 2, diff --git a/app/lib/widgets/dde_text_field.dart b/app/lib/widgets/dde_text_field.dart index 1dd1724..17fd26d 100644 --- a/app/lib/widgets/dde_text_field.dart +++ b/app/lib/widgets/dde_text_field.dart @@ -7,12 +7,14 @@ import 'package:provider/provider.dart'; class DTextField extends StatefulWidget { final String? initText; final String? hint; + final bool readOnly; final Function(String value) onComplete; const DTextField({ Key? key, this.initText, this.hint, + this.readOnly = false, required this.onComplete, }) : super(key: key); @@ -62,7 +64,7 @@ class _DTextFieldState extends State { color: Colors.grey.withOpacity(.3), border: Border.all( width: 2, - color: Focus.of(context).hasFocus + color: Focus.of(context).hasFocus && !widget.readOnly ? context.watch().activeColor ?? Color(0xff565656) : Color(0xff565656)), ), @@ -71,6 +73,7 @@ class _DTextFieldState extends State { child: Padding( padding: const EdgeInsets.only(left: 15), child: TextField( + readOnly: widget.readOnly, focusNode: _focusNode, cursorColor: context.watch().activeColor, decoration: InputDecoration.collapsed(hintText: widget.hint),