diff --git a/app/lib/models/scheme.dart b/app/lib/models/scheme.dart index 4b54d4f..b88d465 100644 --- a/app/lib/models/scheme.dart +++ b/app/lib/models/scheme.dart @@ -8,6 +8,109 @@ import 'package:uuid/uuid.dart'; typedef OnEditEnd(GestureProp prop); +class _TreeNode { + late List nodes; + + bool get fullFiled => nodes.every((element) => (element as _TreeNode).fullFiled); + + T get availableNode => nodes.firstWhere((element) => !(element as _TreeNode).fullFiled); +} + +class GestureDirectionNode extends _TreeNode { + GestureDirection direction; + bool available = true; + + GestureDirectionNode({required this.direction}); + + @override + get fullFiled => !available; + + get availableNode => null; +} + +class SchemeGestureNode extends _TreeNode { + Gesture type; + + SchemeGestureNode({required this.type}) { + switch (type) { + case Gesture.tap: + nodes = [GestureDirectionNode(direction: GestureDirection.none)]; + break; + case Gesture.swipe: + nodes = [ + GestureDirectionNode(direction: GestureDirection.up), + GestureDirectionNode(direction: GestureDirection.down), + GestureDirectionNode(direction: GestureDirection.left), + GestureDirectionNode(direction: GestureDirection.right), + ]; + break; + case Gesture.pinch: + nodes = [ + GestureDirectionNode(direction: GestureDirection.pinch_in), + GestureDirectionNode(direction: GestureDirection.pinch_out), + ]; + } + } +} + +class SchemeTreeNode extends _TreeNode { + int fingers; + + SchemeTreeNode({required this.fingers}); + + @override + List nodes = [ + SchemeGestureNode(type: Gesture.tap), + SchemeGestureNode(type: Gesture.swipe), + SchemeGestureNode(type: Gesture.pinch), + ]; +} + +class SchemeTree extends _TreeNode { + @override + List nodes = [ + SchemeTreeNode(fingers: 3), + SchemeTreeNode(fingers: 4), + SchemeTreeNode(fingers: 5), + ]; + + @override + String toString() => ''' + 3: + tap: ${nodes[0].nodes[0].nodes[0].available} + swipe: + ↑: ${nodes[0].nodes[1].nodes[0].available} + ↓: ${nodes[0].nodes[1].nodes[1].available} + ←: ${nodes[0].nodes[1].nodes[2].available} + →: ${nodes[0].nodes[1].nodes[3].available} + pinch: + in: ${nodes[0].nodes[2].nodes[0].available} + out:${nodes[0].nodes[2].nodes[1].available} + + 4: + tap: ${nodes[1].nodes[0].nodes[0].available} + swipe: + ↑: ${nodes[1].nodes[1].nodes[0].available} + ↓: ${nodes[1].nodes[1].nodes[1].available} + ←: ${nodes[1].nodes[1].nodes[2].available} + →: ${nodes[1].nodes[1].nodes[3].available} + pinch: + in: ${nodes[1].nodes[2].nodes[0].available} + out:${nodes[1].nodes[2].nodes[1].available} + + 5: + tap: ${nodes[2].nodes[0].nodes[0].available} + swipe: + ↑: ${nodes[2].nodes[1].nodes[0].available} + ↓: ${nodes[2].nodes[1].nodes[1].available} + ←: ${nodes[2].nodes[1].nodes[2].available} + →: ${nodes[2].nodes[1].nodes[3].available} + pinch: + in: ${nodes[2].nodes[2].nodes[0].available} + out:${nodes[2].nodes[2].nodes[1].available} + '''; +} + @ProviderModel(copyable: true) class Scheme { @ProviderModelProp() @@ -41,6 +144,16 @@ class Scheme { Scheme.create({this.name, this.description, this.gestures}) { this.id = Uuid().v1(); } + + SchemeTree buildSchemeTree() { + var schemeTree = SchemeTree(); + this.gestures!.forEach((gesture) { + var schemeTreeNode = schemeTree.nodes.firstWhere((ele) => ele.fingers == gesture.fingers); + var schemeGestureNode = schemeTreeNode.nodes.firstWhere((element) => element.type == gesture.gesture); + schemeGestureNode.nodes.firstWhere((element) => element.direction == gesture.direction).available = false; + }); + return schemeTree; + } } enum Gesture { diff --git a/app/lib/pages/content.dart b/app/lib/pages/content.dart index daa897f..a674c94 100644 --- a/app/lib/pages/content.dart +++ b/app/lib/pages/content.dart @@ -1,10 +1,11 @@ import 'package:dde_gesture_manager/extensions.dart'; +import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:dde_gesture_manager/models/scheme.provider.dart'; import 'package:dde_gesture_manager/pages/gesture_editor.dart'; import 'package:dde_gesture_manager/pages/local_manager.dart'; import 'package:dde_gesture_manager/pages/market.dart'; -import 'package:flutter/material.dart'; -import 'package:dde_gesture_manager/models/content_layout.provider.dart'; import 'package:dde_gesture_manager/utils/helper.dart'; +import 'package:flutter/material.dart'; class Content extends StatefulWidget { const Content({Key? key}) : super(key: key); @@ -13,6 +14,10 @@ class Content extends StatefulWidget { _ContentState createState() => _ContentState(); } +class CopiedGesturePropProvider extends GesturePropProvider { + CopiedGesturePropProvider.empty() : super.empty(); +} + class _ContentState extends State { double? preWindowWidth; @@ -21,10 +26,17 @@ class _ContentState extends State { var windowWidth = MediaQuery.of(context).size.width; var preferredPanelsStatus = H.getPreferredPanelsStatus(windowWidth); var widthChanged = preWindowWidth != null && preWindowWidth != windowWidth; - var widget = ChangeNotifierProvider( - create: (context) => ContentLayoutProvider() - ..localManagerOpened = preferredPanelsStatus.localManagerPanelOpened - ..marketOpened = preferredPanelsStatus.marketPanelOpened, + var widget = MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (context) => ContentLayoutProvider() + ..localManagerOpened = preferredPanelsStatus.localManagerPanelOpened + ..marketOpened = preferredPanelsStatus.marketPanelOpened, + ), + ChangeNotifierProvider( + create: (context) => CopiedGesturePropProvider.empty(), + ), + ], builder: (context, child) { if (widthChanged && mounted) { Future.microtask( diff --git a/app/lib/pages/gesture_editor.dart b/app/lib/pages/gesture_editor.dart index 868d8b4..aa74efb 100644 --- a/app/lib/pages/gesture_editor.dart +++ b/app/lib/pages/gesture_editor.dart @@ -5,6 +5,7 @@ import 'package:dde_gesture_manager/models/content_layout.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'; +import 'package:dde_gesture_manager/pages/content.dart'; import 'package:dde_gesture_manager/utils/helper.dart'; import 'package:dde_gesture_manager/utils/keyboard_mapper.dart'; import 'package:dde_gesture_manager/widgets/dde_button.dart'; @@ -13,6 +14,7 @@ import 'package:dde_gesture_manager/widgets/table_cell_shortcut_listener.dart'; import 'package:dde_gesture_manager/widgets/table_cell_text_field.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:uuid/uuid.dart'; const double _headingRowHeight = 56; const double _scrollBarWidth = 14; @@ -152,7 +154,86 @@ class GestureEditor extends StatelessWidget { ), ), ), - Container(height: 10), + Builder(builder: (context) { + var gesturePropProvider = context.watch(); + var copiedGesturePropProvider = context.watch(); + var schemeTree = schemeProvider.buildSchemeTree(); + return Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + DButton.add( + enabled: !gesturePropProvider.editMode! && !schemeTree.fullFiled, + onTap: () { + var schemeProvider = context.read(); + context.read().setProps( + gestures: [ + ...?schemeProvider.gestures, + H.getNextAvailableGestureProp(schemeProvider.buildSchemeTree())!, + ]..sort()); + }, + ), + DButton.delete( + enabled: gesturePropProvider != GestureProp.empty() && !gesturePropProvider.editMode!, + onTap: () { + var schemeProvider = context.read(); + var index = schemeProvider.gestures?.indexWhere((e) => e.id == gesturePropProvider.id); + var newGestures = [ + ...?schemeProvider.gestures?..removeAt(index!), + ]; + context.read().setProps(gestures: newGestures); + if (newGestures.length > 0) + gesturePropProvider.copyFrom( + newGestures[(index ?? 0) > newGestures.length - 1 ? newGestures.length - 1 : index ?? 0] + ..editMode = false); + }, + ), + DButton.duplicate( + enabled: gesturePropProvider != GestureProp.empty() && !gesturePropProvider.editMode!, + onTap: () { + var schemeProvider = context.read(); + context.read().copyFrom( + schemeProvider.gestures!.firstWhere((element) => element.id == gesturePropProvider.id)); + + /// todo: give some info to UI. + }, + ), + DButton.paste( + enabled: copiedGesturePropProvider != CopiedGesturePropProvider.empty() && + !gesturePropProvider.editMode! && + !schemeTree.fullFiled, + onTap: () { + var schemeTree = context.read().buildSchemeTree(); + late GestureProp newGestureProp; + if (schemeTree.nodes + .firstWhere((e) => e.fingers == copiedGesturePropProvider.fingers) + .nodes + .firstWhere((e) => e.type == copiedGesturePropProvider.gesture) + .nodes + .firstWhere((e) => e.direction == copiedGesturePropProvider.direction) + .available) { + newGestureProp = GestureProp.empty()..copyFrom(copiedGesturePropProvider); + } else { + newGestureProp = H.getNextAvailableGestureProp(schemeProvider.buildSchemeTree())!; + newGestureProp.type = copiedGesturePropProvider.type; + newGestureProp.command = copiedGesturePropProvider.command; + newGestureProp.remark = copiedGesturePropProvider.remark; + } + newGestureProp.id = Uuid().v1(); + context.read().setProps( + gestures: [ + ...?schemeProvider.gestures, + newGestureProp, + ]..sort()); + }, + ), + ] + .map((e) => Padding( + padding: const EdgeInsets.only(top: 3.0, right: 10.0, bottom: 8.0), + child: e, + )) + .toList(), + ); + }), Container( height: 300, decoration: BoxDecoration( @@ -202,114 +283,144 @@ List _buildDataRows(List? gestures, BuildContext context) } }, selected: selected, - cells: editing ? _buildRowCellsEditing(context, gesture) : _buildRowCellsNormal(context, selected, gesture), + cells: editing ? _buildRowCellsEditing(context) : _buildRowCellsNormal(context, selected, gesture), ); }).toList(); -List _buildRowCellsEditing(BuildContext context, GestureProp gesture) => [ - DButton.dropdown( - enabled: true, - child: DropdownButton( - icon: Icon(Icons.keyboard_arrow_down_rounded), - items: [3, 4, 5] - .map( - (e) => DropdownMenuItem( - child: Text('$e'), - value: e, - ), - ) - .toList(), - value: context.watch().fingers, - onChanged: (value) => context.read().setProps( - fingers: value, - editMode: true, +List _buildRowCellsEditing(BuildContext context) { + var gesture = context.read(); + var schemeTree = context.read().buildSchemeTree(); + var availableFingers = schemeTree.nodes.where((node) => !node.fullFiled).map((e) => e.fingers); + if (!availableFingers.contains(gesture.fingers)) { + availableFingers = [...availableFingers, gesture.fingers!]..sort(); + } + + var availableGestures = schemeTree.nodes + .firstWhere((node) => node.fingers == gesture.fingers) + .nodes + .where((node) => !node.fullFiled) + .map((e) => e.type); + if (!availableGestures.any((type) => type == gesture.gesture)) { + availableGestures = [...availableGestures, gesture.gesture!]..sort(); + } + + var availableDirection = schemeTree.nodes + .firstWhere((node) => node.fingers == gesture.fingers) + .nodes + .firstWhere((node) => node.type == gesture.gesture) + .nodes + .where((node) => !node.fullFiled) + .map((e) => e.direction); + + if (!availableDirection.any((direction) => direction == gesture.direction)) { + availableDirection = [...availableDirection, gesture.direction!]..sort((a, b) => a.index - b.index); + } + + return [ + DButton.dropdown( + enabled: true, + child: DropdownButton( + icon: Icon(Icons.keyboard_arrow_down_rounded), + items: availableFingers + .map( + (e) => DropdownMenuItem( + child: Text('$e'), + value: e, ), - isExpanded: true, - ), + ) + .toList(), + value: gesture.fingers, + onChanged: (value) => context.read().setProps( + fingers: value, + editMode: true, + ), + isExpanded: true, ), - DButton.dropdown( - enabled: true, - width: 60.0, - child: DropdownButton( - icon: Icon(Icons.keyboard_arrow_down_rounded), - items: Gesture.values - .map( - (e) => DropdownMenuItem( - child: Text( - '${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(e)}', - textScaleFactor: .8, - ).tr(), - value: e, - ), - ) - .toList(), - value: context.watch().gesture, - onChanged: (value) => context.read().setProps( - gesture: value, - editMode: true, + ), + DButton.dropdown( + enabled: true, + width: 100.0, + child: DropdownButton( + icon: Icon(Icons.keyboard_arrow_down_rounded), + items: availableGestures + .map( + (e) => DropdownMenuItem( + child: Text( + '${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(e)}', + textScaleFactor: .8, + ).tr(), + value: e, ), - isExpanded: true, - ), + ) + .toList(), + value: gesture.gesture, + onChanged: (value) => context.read().setProps( + gesture: value, + editMode: true, + ), + isExpanded: true, ), - DButton.dropdown( - enabled: true, - width: 100.0, - child: DropdownButton( - icon: Icon(Icons.keyboard_arrow_down_rounded), - items: GestureDirection.values - .map( - (e) => DropdownMenuItem( - child: Text( - '${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(e)}', - textScaleFactor: .8, - ).tr(), - value: e, - ), - ) - .toList(), - value: context.watch().direction, - onChanged: (value) => context.read().setProps( - direction: value, - editMode: true, + ), + DButton.dropdown( + enabled: true, + width: 100.0, + child: DropdownButton( + icon: Icon(Icons.keyboard_arrow_down_rounded), + items: availableDirection + .map( + (e) => DropdownMenuItem( + child: Text( + '${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(e)}', + textScaleFactor: .8, + ).tr(), + value: e, ), - isExpanded: true, - ), + ) + .toList(), + value: gesture.direction, + onChanged: (value) => context.read().setProps( + direction: value, + editMode: true, + ), + isExpanded: true, ), - DButton.dropdown( - enabled: true, - width: 100.0, - child: DropdownButton( - icon: Icon(Icons.keyboard_arrow_down_rounded), - items: GestureType.values - .map( - (e) => DropdownMenuItem( - child: Text( - '${LocaleKeys.gesture_editor_types}.${H.getGestureTypeName(e)}', - textScaleFactor: .8, - ).tr(), - value: e, - ), - ) - .toList(), - value: context.watch().type, - onChanged: (value) => context.read().setProps( - type: value, - command: '', - editMode: true, + ), + DButton.dropdown( + enabled: true, + width: 100.0, + child: DropdownButton( + icon: Icon(Icons.keyboard_arrow_down_rounded), + items: GestureType.values + .map( + (e) => DropdownMenuItem( + child: Text( + '${LocaleKeys.gesture_editor_types}.${H.getGestureTypeName(e)}', + textScaleFactor: .8, + ).tr(), + value: e, ), - isExpanded: true, - ), - ), - _buildCommandCellsEditing(context), - TableCellTextField( - initText: gesture.remark, - hint: 'pls input cmd', - onComplete: (value) => context.read().setProps( - remark: value, + ) + .toList(), + value: gesture.type, + onChanged: (value) => context.read().setProps( + type: value, + command: '', editMode: true, ), + isExpanded: true, ), - ].map((e) => DDataCell(e)).toList(); + ), + _buildCommandCellsEditing(context), + TableCellTextField( + initText: gesture.remark, + hint: 'pls input cmd', + onComplete: (value) => context.read().setProps( + remark: value, + editMode: true, + ), + ), + ].map((e) => DDataCell(e)).toList(); +} Widget _buildCommandCellsEditing(BuildContext context) { var gesture = context.read(); @@ -414,9 +525,13 @@ List _buildRowCellsNormal(BuildContext context, bool selected, Gestur }, ).toList(), ) - : Text( - gesture.command ?? '', - ), + : (gesture.type == GestureType.built_in + ? Text( + ('${LocaleKeys.built_in_commands}.${(builtInCommands.contains(gesture.command) ? gesture.command : builtInCommands.first)!}') + .tr()) + : Text( + gesture.command ?? '', + )), Text( gesture.remark ?? '', ), diff --git a/app/lib/pages/home.dart b/app/lib/pages/home.dart index 50d1f8c..f425962 100644 --- a/app/lib/pages/home.dart +++ b/app/lib/pages/home.dart @@ -28,7 +28,7 @@ class _HomePageState extends State { "direction": "down", "fingers": 3, "type": "shortcut", - "command": "ctrl+w", + "command": "Control_L+w", "remark": "close current page." }, { @@ -36,7 +36,7 @@ class _HomePageState extends State { "direction": "up", "fingers": 3, "type": "shortcut", - "command": "ctrl+alt+t", + "command": "Control_L+Alt_L+t", "remark": "reopen last closed page." }, { @@ -44,7 +44,7 @@ class _HomePageState extends State { "direction": "in", "fingers": 4, "type": "shortcut", - "command": "ctrl+alt+f", + "command": "Control_L+Alt_L+f", "remark": "search files." }, { diff --git a/app/lib/pages/local_manager.dart b/app/lib/pages/local_manager.dart index 137ba5e..da9e169 100644 --- a/app/lib/pages/local_manager.dart +++ b/app/lib/pages/local_manager.dart @@ -2,6 +2,7 @@ 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'; import 'package:dde_gesture_manager/widgets/dde_button.dart'; @@ -111,6 +112,7 @@ class _LocalManagerState extends State { setState(() { _selectedIndex = index; }); + context.read().copyFrom(GestureProp.empty()); }, child: MouseRegion( cursor: SystemMouseCursors.click, diff --git a/app/lib/utils/helper.dart b/app/lib/utils/helper.dart index 4b891ef..6752dcb 100644 --- a/app/lib/utils/helper.dart +++ b/app/lib/utils/helper.dart @@ -1,9 +1,10 @@ +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/scheme.dart'; import 'package:flutter/cupertino.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:dde_gesture_manager/constants/constants.dart'; -import 'package:dde_gesture_manager/extensions.dart'; +import 'package:uuid/uuid.dart'; class H { H._(); @@ -85,10 +86,10 @@ class H { GestureDirection.none; static String? getGestureTypeName(GestureType? type) => const { - GestureType.built_in: 'built_in', - GestureType.shortcut: 'shortcut', - GestureType.commandline: 'commandline', - }[type]; + GestureType.built_in: 'built_in', + GestureType.shortcut: 'shortcut', + GestureType.commandline: 'commandline', + }[type]; static GestureType getGestureTypeByName(String typeName) => const { @@ -105,6 +106,18 @@ class H { var rgba = list.map((e) => int.parse(e) ~/ 257).toList(); return Color.fromARGB(rgba[3], rgba[0], rgba[1], rgba[2]); } + + static GestureProp? getNextAvailableGestureProp(SchemeTree tree) { + var gestureProp = GestureProp.empty() + ..id = Uuid().v1() + ..type = GestureType.built_in + ..command = builtInCommands.first; + if (tree.fullFiled) return null; + gestureProp.fingers = tree.availableNode.fingers; + gestureProp.gesture = tree.availableNode.availableNode.type; + gestureProp.direction = tree.availableNode.availableNode.availableNode.direction; + return gestureProp; + } } class PreferredPanelsStatus { diff --git a/app/lib/widgets/dde_button.dart b/app/lib/widgets/dde_button.dart index 77a00d6..38bcbc0 100644 --- a/app/lib/widgets/dde_button.dart +++ b/app/lib/widgets/dde_button.dart @@ -33,7 +33,7 @@ class DButton extends StatefulWidget { key: key, width: width, height: height, - onTap: onTap, + onTap: enabled ? onTap : null, child: Tooltip( child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.add, size: 18)), message: LocaleKeys.operation_add.tr(), @@ -50,7 +50,7 @@ class DButton extends StatefulWidget { key: key, width: width, height: height, - onTap: onTap, + onTap: enabled ? onTap : null, child: Tooltip( child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.remove, size: 18)), message: LocaleKeys.operation_delete.tr(), @@ -67,7 +67,7 @@ class DButton extends StatefulWidget { key: key, width: width, height: height, - onTap: onTap, + onTap: enabled ? onTap : null, child: Tooltip( child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.check, size: 18)), message: LocaleKeys.operation_apply.tr(), @@ -84,12 +84,29 @@ class DButton extends StatefulWidget { key: key, width: width, height: height, - onTap: onTap, + onTap: enabled ? onTap : null, child: Tooltip( child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.copy_rounded, size: 18)), message: LocaleKeys.operation_duplicate.tr(), )); + factory DButton.paste({ + Key? key, + required enabled, + GestureTapCallback? onTap, + height = defaultButtonHeight * .7, + width = defaultButtonHeight * .7, + }) => + DButton( + key: key, + width: width, + height: height, + onTap: enabled ? onTap : null, + child: Tooltip( + child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.paste_rounded, size: 18)), + message: LocaleKeys.operation_paste.tr(), + )); + factory DButton.dropdown({ Key? key, width = 60.0, diff --git a/app/lib/widgets/table_cell_text_field.dart b/app/lib/widgets/table_cell_text_field.dart index 3404173..d1f114c 100644 --- a/app/lib/widgets/table_cell_text_field.dart +++ b/app/lib/widgets/table_cell_text_field.dart @@ -1,6 +1,7 @@ import 'package:dde_gesture_manager/constants/constants.dart'; import 'package:dde_gesture_manager/models/settings.provider.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; class TableCellTextField extends StatefulWidget { @@ -21,7 +22,9 @@ class TableCellTextField extends StatefulWidget { class _TableCellTextFieldState extends State { final FocusNode _focusNode = FocusNode( - onKeyEvent: (_, __) => KeyEventResult.skipRemainingHandlers, + onKeyEvent: (_, evt) => [LogicalKeyboardKey.backspace].contains(evt.logicalKey) + ? KeyEventResult.ignored + : KeyEventResult.skipRemainingHandlers, ); final TextEditingController _controller = TextEditingController(); diff --git a/app/pubspec.yaml b/app/pubspec.yaml index b751a2c..7056b83 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 - window_manager: ^0.0.3 + window_manager: ^0.0.5 localstorage: ^4.0.0+1 shared_preferences: ^2.0.7 xdg_directories: 0.2.0 diff --git a/app/resources/langs/en.json b/app/resources/langs/en.json index 9790aad..389276f 100644 --- a/app/resources/langs/en.json +++ b/app/resources/langs/en.json @@ -49,7 +49,7 @@ "gestures": { "swipe": "swipe", "pinch": "pinch", - "tap": "pinch" + "tap": "tap" }, "types": { "built_in": "built-in", @@ -61,7 +61,8 @@ "add": "Add", "delete": "delete", "duplicate": "duplicate", - "apply": "apply" + "apply": "apply", + "paste": "paste" }, "str": { "null": "Null" diff --git a/app/resources/langs/zh-CN.json b/app/resources/langs/zh-CN.json index 2883e08..00e0f2d 100644 --- a/app/resources/langs/zh-CN.json +++ b/app/resources/langs/zh-CN.json @@ -61,7 +61,8 @@ "add": "新增", "delete": "删除", "duplicate": "复制", - "apply": "应用" + "apply": "应用", + "paste": "粘贴" }, "str": { "null": "无"