diff --git a/app/lib/models/local_schemes.dart b/app/lib/models/local_schemes.dart index 8d841df..9108a32 100644 --- a/app/lib/models/local_schemes.dart +++ b/app/lib/models/local_schemes.dart @@ -2,7 +2,7 @@ import 'package:dde_gesture_manager/models/scheme.dart'; export 'local_schemes_web.dart' if (dart.library.io) 'local_schemes_linux.dart'; -abstract class LocalSchemeEntry { +abstract class LocalSchemeEntry implements Comparable { Scheme scheme; DateTime lastModifyTime; String path; @@ -25,4 +25,4 @@ abstract class LocalSchemeEntry { abstract class LocalSchemesInterface { Future> get schemeEntries; -} \ No newline at end of file +} diff --git a/app/lib/models/local_schemes_linux.dart b/app/lib/models/local_schemes_linux.dart index 105dd79..e118cb0 100644 --- a/app/lib/models/local_schemes_linux.dart +++ b/app/lib/models/local_schemes_linux.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:dde_gesture_manager/builder/provider_annotation.dart'; @@ -13,7 +14,7 @@ export 'local_schemes.dart'; @ProviderModel() class LocalSchemes implements LocalSchemesInterface { LocalSchemes() { - schemeEntries.then((value) => schemes = [LocalSchemeEntryLinux.systemDefault(), ...value]); + schemeEntries.then((value) => schemes = [LocalSchemeEntryLinux.systemDefault(), ...value..sort()]); } @override @@ -68,7 +69,13 @@ class LocalSchemeEntryLinux implements LocalSchemeEntry { @override save() { - // TODO: implement save - throw UnimplementedError(); + var file = File(path); + file.writeAsStringSync(json.encode(scheme)); + } + + @override + int compareTo(other) { + assert(other is LocalSchemeEntry); + return lastModifyTime.isAfter(other.lastModifyTime) ? -1 : 1; } } diff --git a/app/lib/models/local_schemes_web.dart b/app/lib/models/local_schemes_web.dart index c8c1814..e252c36 100644 --- a/app/lib/models/local_schemes_web.dart +++ b/app/lib/models/local_schemes_web.dart @@ -12,7 +12,7 @@ export 'local_schemes.dart'; @ProviderModel() class LocalSchemes implements LocalSchemesInterface { LocalSchemes() { - schemeEntries.then((value) => schemes = [LocalSchemeEntryWeb.systemDefault(), ...value]); + schemeEntries.then((value) => schemes = [LocalSchemeEntryWeb.systemDefault(), ...value..sort()]); } @override @@ -72,4 +72,10 @@ class LocalSchemeEntryWeb implements LocalSchemeEntry { // TODO: implement save throw UnimplementedError(); } + + @override + int compareTo(other) { + assert(other is LocalSchemeEntry); + return lastModifyTime.isAfter(other.lastModifyTime) ? -1 : 1; + } } diff --git a/app/lib/models/scheme.dart b/app/lib/models/scheme.dart index b88d465..8f9d42c 100644 --- a/app/lib/models/scheme.dart +++ b/app/lib/models/scheme.dart @@ -128,7 +128,7 @@ class Scheme { Scheme.parse(scheme) { if (scheme is String) scheme = json.decode(scheme); assert(scheme is Map); - id = scheme['id']; + id = scheme['id'] ?? Uuid().v1(); name = scheme['name']; description = scheme['desc']; gestures = (scheme['gestures'] as List? ?? []).map((ele) => GestureProp.parse(ele)).toList()..sort(); @@ -154,6 +154,13 @@ class Scheme { }); return schemeTree; } + + Map toJson() => { + 'id': id, + 'name': name, + 'desc': description, + 'gestures': gestures, + }; } enum Gesture { @@ -221,6 +228,16 @@ class GestureProp implements Comparable { return 'GestureProp{gesture: $gesture, direction: $direction, fingers: $fingers, type: $type, command: $command, remark: $remark}'; } + Map toJson() => { + 'id': id, + 'gesture': H.getGestureName(gesture), + 'direction': H.getGestureDirectionName(direction), + 'fingers': fingers, + 'type': H.getGestureTypeName(type), + 'command': command, + 'remark': remark, + }; + GestureProp.empty() : this.id = Uuid.NAMESPACE_NIL; GestureProp.parse(props) { diff --git a/app/lib/pages/gesture_editor.dart b/app/lib/pages/gesture_editor.dart index bd56562..21fb172 100644 --- a/app/lib/pages/gesture_editor.dart +++ b/app/lib/pages/gesture_editor.dart @@ -2,6 +2,7 @@ import 'package:adaptive_scrollbar/adaptive_scrollbar.dart'; import 'package:dde_gesture_manager/constants/constants.dart'; import 'package:dde_gesture_manager/extensions.dart'; import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:dde_gesture_manager/models/local_schemes_provider.dart'; import 'package:dde_gesture_manager/models/scheme.dart'; import 'package:dde_gesture_manager/models/scheme.provider.dart'; import 'package:dde_gesture_manager/models/settings.provider.dart'; @@ -256,9 +257,25 @@ class GestureEditor extends StatelessWidget { ), Expanded( child: DTextField( + initText: schemeProvider.name, onComplete: (val) { + val = val.trim(); schemeProvider.setProps(name: val); - /// todo: change name to local list. + var localSchemesProvider = context.read(); + if (!localSchemesProvider.schemes!.every((element) => element.scheme.name != val)) { + /// show error info; + 'duplicate name'.sout(); + return; + } + ; + 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()]); + }); }, ), ), diff --git a/app/lib/pages/local_manager.dart b/app/lib/pages/local_manager.dart index da9e169..da3fbe9 100644 --- a/app/lib/pages/local_manager.dart +++ b/app/lib/pages/local_manager.dart @@ -10,6 +10,7 @@ import 'package:flutter/animation.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; +import 'package:uuid/uuid.dart'; class LocalManager extends StatefulWidget { const LocalManager({ @@ -22,22 +23,22 @@ class LocalManager extends StatefulWidget { class _LocalManagerState extends State { late ScrollController _scrollController; - int? _hoveringIndex; - late int _selectedIndex; + String? _hoveringItem; + late String _selectedItem; @override void initState() { super.initState(); /// todo: load from sp - _selectedIndex = 0; + _selectedItem = Uuid.NAMESPACE_NIL; _scrollController = ScrollController(); } - Color _getItemBackgroundColor(int index) { + Color _getItemBackgroundColor(int index, String itemId) { Color _color = index % 2 == 0 ? context.t.scaffoldBackgroundColor : context.t.backgroundColor; - if (index == _hoveringIndex) _color = context.t.scaffoldBackgroundColor; - if (index == _selectedIndex) _color = context.read().currentActiveColor; + if (itemId == _hoveringItem) _color = context.t.scaffoldBackgroundColor; + if (itemId == _selectedItem) _color = context.read().currentActiveColor; return _color; } @@ -110,7 +111,7 @@ class _LocalManagerState extends State { onTap: () { context.read().copyFrom(localSchemes[index].scheme); setState(() { - _selectedIndex = index; + _selectedItem = localSchemes[index].scheme.id!; }); context.read().copyFrom(GestureProp.empty()); }, @@ -118,16 +119,17 @@ class _LocalManagerState extends State { cursor: SystemMouseCursors.click, onEnter: (_) { setState(() { - _hoveringIndex = index; + _hoveringItem = localSchemes[index].scheme.id!; }); }, child: Container( - color: _getItemBackgroundColor(index), + color: _getItemBackgroundColor(index, localSchemes[index].scheme.id!), child: Padding( padding: const EdgeInsets.only(left: 6, right: 12.0), child: DefaultTextStyle( style: context.t.textTheme.bodyText2!.copyWith( - color: _selectedIndex == index ? Colors.white : null, + color: + _selectedItem == localSchemes[index].scheme.id! ? Colors.white : null, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -152,9 +154,9 @@ class _LocalManagerState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ DButton.add(enabled: true), - DButton.delete(enabled: _selectedIndex > 0), - DButton.duplicate(enabled: _selectedIndex > 0), - DButton.apply(enabled: _selectedIndex > 0), + DButton.delete(enabled: _selectedItem != Uuid.NAMESPACE_NIL), + DButton.duplicate(enabled: _selectedItem != Uuid.NAMESPACE_NIL), + DButton.apply(enabled: _selectedItem != Uuid.NAMESPACE_NIL), ] .map((e) => Padding( padding: const EdgeInsets.only(right: 4), diff --git a/app/lib/widgets/dde_text_field.dart b/app/lib/widgets/dde_text_field.dart index 91ba092..1dd1724 100644 --- a/app/lib/widgets/dde_text_field.dart +++ b/app/lib/widgets/dde_text_field.dart @@ -1,8 +1,8 @@ import 'package:dde_gesture_manager/constants/constants.dart'; +import 'package:dde_gesture_manager/extensions.dart'; import 'package:dde_gesture_manager/models/settings.provider.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:dde_gesture_manager/extensions.dart'; class DTextField extends StatefulWidget { final String? initText; @@ -44,6 +44,14 @@ class _DTextFieldState extends State { } @override + void didUpdateWidget(covariant DTextField oldWidget) { + if (oldWidget.initText != widget.initText) { + _controller.text = widget.initText ?? ''; + } + super.didUpdateWidget(oldWidget); + } + + @override Widget build(BuildContext context) { return Focus( child: Builder(builder: (context) {