Merge pull request 'Editor almost done.' (#3) from dev into master

Reviewed-on: #3
master
DebuggerX 4 years ago
commit 02bb25e990

@ -22,6 +22,8 @@ class ProviderGenerator extends GeneratorForAnnotation<ProviderModel> {
List<AnnotationField> fields = [];
element.fields.forEach((field) {
var annotation = field.metadata.firstWhereOrNull(
(m) => m.computeConstantValue()?.type?.getDisplayString(withNullability: true) == 'ProviderModelProp') ??
field.getter?.metadata.firstWhereOrNull(
(m) => m.computeConstantValue()?.type?.getDisplayString(withNullability: true) == 'ProviderModelProp');
if (annotation != null)
fields.add(
@ -77,7 +79,7 @@ String? _genCopyFunc(String displayName, List<AnnotationField> fields, bool copy
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')}
${fields.map((f) => 'if (other.${f.name} != this.${f.name}) {this.${f.name} = other.${f.name}; changed = true; }').join('\n')}
if (changed) notifyListeners();
}
''';

@ -20,6 +20,23 @@ const double defaultBorderRadius = 8;
const double defaultButtonHeight = 36;
const List<String> builtInCommands = [
'ShowWorkspace',
'Handle4Or5FingersSwipeUp',
'Handle4Or5FingersSwipeDown',
'ToggleMaximize',
'Minimize',
'ShowWindow',
'ShowAllWindow',
'SwitchApplication',
'ReverseSwitchApplication',
'SwitchWorkspace',
'ReverseSwitchWorkspace',
'SplitWindowLeft',
'SplitWindowRight',
'MoveWindow',
];
enum PanelType {
local_manager,
market,

@ -18,5 +18,7 @@ const supportedLocaleNames = {
SupportedLocale.en: 'English',
};
Locale getSupportedLocale(SupportedLocale supportedLocale) => supportedLocales[supportedLocale.index];
Locale transformSupportedLocale(SupportedLocale supportedLocale) => supportedLocales[supportedLocale.index];
SupportedLocale? getSupportedLocale(Locale? locale) =>
supportedLocales.contains(locale) ? SupportedLocale.values[supportedLocales.indexOf(locale!)] : null;

@ -0,0 +1,28 @@
import 'package:dde_gesture_manager/models/scheme.dart';
export 'local_schemes_web.dart' if (dart.library.io) 'local_schemes_linux.dart';
abstract class LocalSchemeEntry {
Scheme scheme;
DateTime lastModifyTime;
String path;
LocalSchemeEntry({
required this.path,
required this.scheme,
required this.lastModifyTime,
});
LocalSchemeEntry.systemDefault()
: this.path = '',
this.scheme = Scheme.systemDefault(),
/// 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();
}
abstract class LocalSchemesInterface<T extends LocalSchemeEntry> {
Future<List<T>> get schemeEntries;
}

@ -0,0 +1,74 @@
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/scheme.dart';
import 'package:path/path.dart' show join;
import 'package:path_provider/path_provider.dart';
import 'local_schemes.dart';
export 'local_schemes.dart';
@ProviderModel()
class LocalSchemes implements LocalSchemesInterface<LocalSchemeEntryLinux> {
LocalSchemes() {
schemeEntries.then((value) => schemes = [LocalSchemeEntryLinux.systemDefault(), ...value]);
}
@override
Future<List<LocalSchemeEntryLinux>> get schemeEntries async {
var _supportDirectory = await getApplicationSupportDirectory();
var directory = Directory(join(_supportDirectory.path, 'schemes'));
if (!directory.existsSync()) directory.createSync();
return directory
.list()
.map<LocalSchemeEntryLinux?>((f) {
LocalSchemeEntryLinux? entry;
try {
var content = File(f.path).readAsStringSync();
entry = LocalSchemeEntryLinux(
path: f.path, scheme: Scheme.parse(content), lastModifyTime: f.statSync().modified);
} catch (e) {
e.sout();
}
return entry;
})
.where((e) => e != null)
.cast<LocalSchemeEntryLinux>()
.toList();
}
@ProviderModelProp()
List<LocalSchemeEntry>? schemes;
}
class LocalSchemeEntryLinux implements LocalSchemeEntry {
@override
String path;
@override
Scheme scheme;
@override
DateTime lastModifyTime;
LocalSchemeEntryLinux({
required this.path,
required this.scheme,
required this.lastModifyTime,
});
LocalSchemeEntryLinux.systemDefault()
: this.path = '',
this.scheme = Scheme.systemDefault(),
/// 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);
@override
save() {
// TODO: implement save
throw UnimplementedError();
}
}

@ -0,0 +1 @@
export 'local_schemes_web.provider.dart' if (dart.library.io) 'local_schemes_linux.provider.dart';

@ -0,0 +1,75 @@
import 'dart:convert';
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/scheme.dart';
import 'local_schemes.dart';
export 'local_schemes.dart';
@ProviderModel()
class LocalSchemes implements LocalSchemesInterface<LocalSchemeEntryWeb> {
LocalSchemes() {
schemeEntries.then((value) => schemes = [LocalSchemeEntryWeb.systemDefault(), ...value]);
}
@override
Future<List<LocalSchemeEntryWeb>> get schemeEntries async {
return window.localStorage.keys
.map<LocalSchemeEntryWeb?>((key) {
if (key.startsWith('schemes.')) {
LocalSchemeEntryWeb? entry;
try {
var content = window.localStorage[key] ?? '';
var schemeJson = json.decode(content);
entry = LocalSchemeEntryWeb(
path: key,
scheme: Scheme.parse(schemeJson),
lastModifyTime: DateTime.parse(schemeJson['modified_at']),
);
} catch (e) {
e.sout();
}
return entry;
}
})
.where((e) => e != null)
.cast<LocalSchemeEntryWeb>()
.toList();
}
@ProviderModelProp()
List<LocalSchemeEntry>? schemes;
}
class LocalSchemeEntryWeb implements LocalSchemeEntry {
@override
String path;
@override
Scheme scheme;
@override
DateTime lastModifyTime;
LocalSchemeEntryWeb({
required this.path,
required this.scheme,
required this.lastModifyTime,
});
LocalSchemeEntryWeb.systemDefault()
: this.path = '',
this.scheme = Scheme.systemDefault(),
/// 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);
@override
save() {
// TODO: implement save
throw UnimplementedError();
}
}

@ -1,21 +0,0 @@
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;
}

@ -1,68 +0,0 @@
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();
}
}

@ -1 +0,0 @@
export 'local_solutions_web.provider.dart' if (dart.library.io) 'local_solutions_linux.provider.dart';

@ -1,67 +0,0 @@
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();
}
}

@ -0,0 +1,144 @@
import 'dart:convert';
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
import 'package:dde_gesture_manager/extensions.dart';
import 'package:dde_gesture_manager/extensions/compare_extension.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:uuid/uuid.dart';
typedef OnEditEnd(GestureProp prop);
@ProviderModel(copyable: true)
class Scheme {
@ProviderModelProp()
String? id;
@ProviderModelProp()
String? name;
@ProviderModelProp()
String? description;
@ProviderModelProp()
List<GestureProp>? gestures;
Scheme.parse(scheme) {
if (scheme is String) scheme = json.decode(scheme);
assert(scheme is Map);
id = scheme['id'];
name = scheme['name'];
description = scheme['desc'];
gestures = (scheme['gestures'] as List? ?? []).map<GestureProp>((ele) => GestureProp.parse(ele)).toList()..sort();
}
Scheme.systemDefault() {
this.id = Uuid.NAMESPACE_NIL;
this.name = LocaleKeys.local_manager_default_scheme_label.tr();
this.description = LocaleKeys.local_manager_default_scheme_description.tr();
this.gestures = [];
}
Scheme.create({this.name, this.description, this.gestures}) {
this.id = Uuid().v1();
}
}
enum Gesture {
tap,
swipe,
pinch,
}
enum GestureDirection {
up,
down,
left,
right,
pinch_in,
pinch_out,
none,
}
enum GestureType {
built_in,
commandline,
shortcut,
}
@ProviderModel(copyable: true)
class GestureProp implements Comparable {
@ProviderModelProp()
String? id;
@ProviderModelProp()
Gesture? gesture;
@ProviderModelProp()
GestureDirection? direction;
@ProviderModelProp()
int? fingers;
@ProviderModelProp()
GestureType? type;
@ProviderModelProp()
String? command;
@ProviderModelProp()
String? remark;
@ProviderModelProp()
bool? get editMode => _editMode;
set editMode(bool? val) {
_editMode = val ?? false;
if (val == false) onEditEnd?.call(this);
}
OnEditEnd? onEditEnd;
bool _editMode = false;
@override
bool operator ==(Object other) => other is GestureProp && other.id == this.id;
@override
String toString() {
return 'GestureProp{gesture: $gesture, direction: $direction, fingers: $fingers, type: $type, command: $command, remark: $remark}';
}
GestureProp.empty() : this.id = Uuid.NAMESPACE_NIL;
GestureProp.parse(props) {
if (props is String) props = json.decode(props);
assert(props is Map);
id = Uuid().v1();
gesture = H.getGestureByName(props['gesture']);
direction = H.getGestureDirectionByName(props['direction']);
fingers = props['fingers'];
type = H.getGestureTypeByName(props['type']);
command = props['command'];
remark = props['remark'];
}
copyFrom(GestureProp prop) {
this.id = prop.id;
this.gesture = prop.gesture;
this.direction = prop.direction;
this.fingers = prop.fingers;
this.type = prop.type;
this.command = prop.command;
this.remark = prop.remark;
}
@override
int compareTo(other) {
assert(other is GestureProp);
if (fingers.diff(other.fingers) && other.fingers != null) return fingers! - other.fingers as int;
if (gesture.diff(other.gesture) && other.gesture != null) return gesture!.index - other.gesture!.index as int;
if (direction.diff(other.direction) && other.direction != null)
return direction!.index - other.direction!.index as int;
return 0;
}
}

@ -1,7 +1,15 @@
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
import 'package:flutter/material.dart';
export 'package:flutter/material.dart' show Color;
@ProviderModel()
class Settings {
@ProviderModelProp()
bool? isDarkMode;
@ProviderModelProp()
Color? activeColor;
Color get currentActiveColor => activeColor ?? const Color(0xff0069cc);
}

@ -1,92 +0,0 @@
import 'dart:convert';
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
@ProviderModel(copyable: true)
class Solution {
@ProviderModelProp()
String? name;
@ProviderModelProp()
String? description;
@ProviderModelProp()
List<GestureProp>? gestures;
Solution.parse(solution) {
if (solution is String) solution = json.decode(solution);
assert(solution is Map);
name = solution['name'];
description = solution['desc'];
gestures = (solution['gestures'] as List? ?? []).map<GestureProp>((ele) => GestureProp.parse(ele)).toList();
}
}
enum Gesture {
swipe,
tap,
pinch,
}
enum GestureDirection {
up,
down,
left,
right,
pinch_in,
pinch_out,
none,
}
enum GestureType {
built_in,
commandline,
shortcut,
}
@ProviderModel(copyable: true)
class GestureProp {
@ProviderModelProp()
Gesture? gesture;
@ProviderModelProp()
GestureDirection? direction;
@ProviderModelProp()
int? fingers;
@ProviderModelProp()
GestureType? type;
@ProviderModelProp()
String? command;
@ProviderModelProp()
String? remark;
@override
bool operator ==(Object other) =>
other is GestureProp &&
other.gesture == this.gesture &&
other.direction == this.direction &&
other.fingers == this.fingers;
@override
String toString() {
return 'GestureProp{gesture: $gesture, direction: $direction, fingers: $fingers, type: $type, command: $command, remark: $remark}';
}
GestureProp.empty();
GestureProp.parse(props) {
if (props is String) props = json.decode(props);
assert(props is Map);
gesture = H.getGestureByName(props['gesture']);
direction = H.getGestureDirectionByName(props['direction']);
fingers = props['fingers'];
type = H.getGestureTypeByName(props['type']);
command = props['command'];
remark = props['remark'];
}
}

@ -1,56 +1,32 @@
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/solution.dart';
import 'package:dde_gesture_manager/models/solution.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/utils/helper.dart';
import 'package:dde_gesture_manager/utils/keyboard_mapper.dart';
import 'package:dde_gesture_manager/widgets/dde_button.dart';
import 'package:dde_gesture_manager/widgets/dde_data_table.dart';
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';
const double _headingRowHeight = 56;
const double _scrollBarWidth = 14;
class GestureEditor extends StatelessWidget {
const GestureEditor({Key? key}) : super(key: key);
List<DDataRow> _buildDataRow(List<GestureProp>? gestures, BuildContext context) => (gestures ?? [])
.map((gesture) => DDataRow(
onSelectChanged: (selected) {
if (selected == true)
context.read<GesturePropProvider>().setProps(
gesture: gesture.gesture,
direction: gesture.direction,
fingers: gesture.fingers,
type: gesture.type,
command: gesture.command,
remark: gesture.remark,
);
},
selected: context.watch<GesturePropProvider>() == gesture,
cells: [
Center(
child: Text('${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(gesture.gesture)}').tr(),
),
Center(
child: Text('${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(gesture.direction)}')
.tr()),
Center(
child: Text('${gesture.fingers}'),
),
Center(child: Text('${LocaleKeys.gesture_editor_types}.${H.getGestureTypeName(gesture.type)}').tr()),
Text(gesture.command ?? ''),
Text(gesture.remark ?? ''),
]
.map(
(ele) => DDataCell(ele),
)
.toList(),
))
.toList();
@override
Widget build(BuildContext context) {
var layoutProvider = context.watch<ContentLayoutProvider>();
var solutionProvider = context.watch<SolutionProvider>();
var schemeProvider = context.watch<SchemeProvider>();
final horizontalCtrl = ScrollController();
final verticalCtrl = ScrollController();
return Flexible(
child: Padding(
padding: const EdgeInsets.all(10),
@ -99,6 +75,10 @@ class GestureEditor extends StatelessWidget {
),
Container(height: 10),
Expanded(
child: GestureDetector(
onTap: () {
context.read<GesturePropProvider>().setProps(editMode: false);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
@ -110,37 +90,60 @@ class GestureEditor extends StatelessWidget {
width: double.infinity,
clipBehavior: Clip.antiAlias,
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
return Scrollbar(
isAlwaysShown: true,
return AdaptiveScrollbar(
controller: verticalCtrl,
underColor: Colors.transparent,
sliderDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(_scrollBarWidth / 2),
color: Colors.grey.withOpacity(.4),
),
sliderActiveDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(_scrollBarWidth / 2),
color: Colors.grey.withOpacity(.6),
),
position: ScrollbarPosition.right,
underSpacing: EdgeInsets.only(top: _headingRowHeight),
width: _scrollBarWidth,
child: AdaptiveScrollbar(
width: _scrollBarWidth,
underColor: Colors.transparent,
sliderDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(_scrollBarWidth / 2),
color: Colors.grey.withOpacity(.4),
),
sliderActiveDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(_scrollBarWidth / 2),
color: Colors.grey.withOpacity(.6),
),
controller: horizontalCtrl,
position: ScrollbarPosition.bottom,
child: SingleChildScrollView(
primary: true,
scrollDirection: Axis.horizontal,
controller: horizontalCtrl,
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth),
child: DDataTable(
showBottomBorder: true,
headingRowHeight: _headingRowHeight,
showCheckboxColumn: true,
headerBackgroundColor: context.t.dialogBackgroundColor,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
border: Border.all(
width: .2,
color: context.t.dividerColor,
),
),
verticalScrollController: verticalCtrl,
dataRowColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) return context.t.dialogBackgroundColor;
if (states.contains(MaterialState.selected)) return Colors.blueAccent;
if (states.contains(MaterialState.selected))
return context.read<SettingsProvider>().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_fingers.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: _buildDataRow(solutionProvider.gestures, context),
rows: _buildDataRows(schemeProvider.gestures, context),
),
),
),
),
@ -148,6 +151,7 @@ class GestureEditor extends StatelessWidget {
}),
),
),
),
Container(height: 10),
Container(
height: 300,
@ -167,3 +171,261 @@ class GestureEditor extends StatelessWidget {
);
}
}
List<DDataRow> _buildDataRows(List<GestureProp>? gestures, BuildContext context) => (gestures ?? []).map((gesture) {
var gesturePropProvider = context.watch<GesturePropProvider>();
bool editing = gesturePropProvider == gesture && gesturePropProvider.editMode == true;
bool selected = gesturePropProvider == gesture && !editing;
return DDataRow(
onSelectChanged: (selected) {
var provider = context.read<GesturePropProvider>();
if (selected == true) {
provider.setProps(
editMode: false,
);
Future.microtask(() => provider.setProps(
id: gesture.id,
));
} else if (selected == false) {
provider.onEditEnd = (prop) {
var schemeProvider = context.read<SchemeProvider>();
var newGestures = List<GestureProp>.of(schemeProvider.gestures!);
var index = newGestures.indexWhere((element) => element == prop);
newGestures[index].copyFrom(prop);
context.read<SchemeProvider>().setProps(
gestures: newGestures..sort(),
);
};
provider.copyFrom(
gesture..editMode = true,
);
}
},
selected: selected,
cells: editing ? _buildRowCellsEditing(context, gesture) : _buildRowCellsNormal(context, selected, gesture),
);
}).toList();
List<DDataCell> _buildRowCellsEditing(BuildContext context, GestureProp gesture) => [
DButton.dropdown(
enabled: true,
child: DropdownButton<int>(
icon: Icon(Icons.keyboard_arrow_down_rounded),
items: [3, 4, 5]
.map(
(e) => DropdownMenuItem<int>(
child: Text('$e'),
value: e,
),
)
.toList(),
value: context.watch<GesturePropProvider>().fingers,
onChanged: (value) => context.read<GesturePropProvider>().setProps(
fingers: value,
editMode: true,
),
isExpanded: true,
),
),
DButton.dropdown(
enabled: true,
width: 60.0,
child: DropdownButton<Gesture>(
icon: Icon(Icons.keyboard_arrow_down_rounded),
items: Gesture.values
.map(
(e) => DropdownMenuItem<Gesture>(
child: Text(
'${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(e)}',
textScaleFactor: .8,
).tr(),
value: e,
),
)
.toList(),
value: context.watch<GesturePropProvider>().gesture,
onChanged: (value) => context.read<GesturePropProvider>().setProps(
gesture: value,
editMode: true,
),
isExpanded: true,
),
),
DButton.dropdown(
enabled: true,
width: 100.0,
child: DropdownButton<GestureDirection>(
icon: Icon(Icons.keyboard_arrow_down_rounded),
items: GestureDirection.values
.map(
(e) => DropdownMenuItem<GestureDirection>(
child: Text(
'${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(e)}',
textScaleFactor: .8,
).tr(),
value: e,
),
)
.toList(),
value: context.watch<GesturePropProvider>().direction,
onChanged: (value) => context.read<GesturePropProvider>().setProps(
direction: value,
editMode: true,
),
isExpanded: true,
),
),
DButton.dropdown(
enabled: true,
width: 100.0,
child: DropdownButton<GestureType>(
icon: Icon(Icons.keyboard_arrow_down_rounded),
items: GestureType.values
.map(
(e) => DropdownMenuItem<GestureType>(
child: Text(
'${LocaleKeys.gesture_editor_types}.${H.getGestureTypeName(e)}',
textScaleFactor: .8,
).tr(),
value: e,
),
)
.toList(),
value: context.watch<GesturePropProvider>().type,
onChanged: (value) => context.read<GesturePropProvider>().setProps(
type: value,
command: '',
editMode: true,
),
isExpanded: true,
),
),
_buildCommandCellsEditing(context),
TableCellTextField(
initText: gesture.remark,
hint: 'pls input cmd',
onComplete: (value) => context.read<GesturePropProvider>().setProps(
remark: value,
editMode: true,
),
),
].map((e) => DDataCell(e)).toList();
Widget _buildCommandCellsEditing(BuildContext context) {
var gesture = context.read<GesturePropProvider>();
switch (gesture.type) {
case GestureType.commandline:
return TableCellTextField(
initText: gesture.command,
hint: 'pls input cmd',
onComplete: (value) => context.read<GesturePropProvider>().setProps(
command: value,
editMode: true,
),
);
case GestureType.built_in:
return DButton.dropdown(
enabled: true,
width: 250.0,
child: DropdownButton<String>(
icon: Icon(Icons.keyboard_arrow_down_rounded),
items: builtInCommands
.map(
(e) => DropdownMenuItem<String>(
child: Text(
('${LocaleKeys.built_in_commands}.$e').tr(),
textScaleFactor: .8,
),
value: ('${LocaleKeys.built_in_commands}.$e').tr(),
),
)
.toList(),
value:
('${LocaleKeys.built_in_commands}.${(builtInCommands.contains(gesture.command) ? gesture.command : builtInCommands.first)!}')
.tr(),
onChanged: (value) => context.read<GesturePropProvider>().setProps(
command: value,
editMode: true,
),
isExpanded: true,
),
);
case GestureType.shortcut:
return TableCellShortcutListener(
width: 250.0,
initShortcut: gesture.command ?? '',
onComplete: (value) => context.read<GesturePropProvider>().setProps(
command: value,
editMode: true,
),
);
default:
throw Exception('Unknown gesture command type.');
}
}
List<DDataCell> _buildRowCellsNormal(BuildContext context, bool selected, GestureProp gesture) => [
Center(
child: Text(
'${gesture.fingers}',
),
),
Center(
child: Text(
'${LocaleKeys.gesture_editor_gestures}.${H.getGestureName(gesture.gesture)}',
).tr(),
),
Center(
child: Text(
'${LocaleKeys.gesture_editor_directions}.${H.getGestureDirectionName(gesture.direction)}',
).tr()),
Center(
child: Text(
'${LocaleKeys.gesture_editor_types}.${H.getGestureTypeName(gesture.type)}',
).tr()),
gesture.type == GestureType.shortcut
? Row(
mainAxisAlignment: MainAxisAlignment.start,
children: (gesture.command ?? '').split('+').map(
(e) {
var keyNames = getPhysicalKeyNamesByRealName(e);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius / 2),
color: context.t.dialogBackgroundColor,
border: Border.all(
width: 1,
color: Color(0xff565656),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: Text(
keyNames != null ? keyNames.displayName : LocaleKeys.str_null.tr(),
style: TextStyle(
color: context.watch<SettingsProvider>().currentActiveColor,
),
),
),
),
);
},
).toList(),
)
: Text(
gesture.command ?? '',
),
Text(
gesture.remark ?? '',
),
]
.map(
(ele) => DDataCell(DefaultTextStyle(
style: context.t.textTheme.bodyText2!.copyWith(
color: selected ? Colors.white : null,
),
child: ele)),
)
.toList();

@ -1,6 +1,6 @@
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/local_schemes_provider.dart';
import 'package:dde_gesture_manager/models/scheme.provider.dart';
import 'package:dde_gesture_manager/pages/content.dart';
import 'package:dde_gesture_manager/pages/footer.dart';
import 'package:flutter/material.dart';
@ -18,7 +18,7 @@ class _HomePageState extends State<HomePage> {
return Scaffold(
body: MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => SolutionProvider.parse('''
ChangeNotifierProvider(create: (context) => SchemeProvider.parse('''
{
"name": "test",
"desc": "some desc",
@ -66,7 +66,7 @@ class _HomePageState extends State<HomePage> {
}
''')),
ChangeNotifierProvider(create: (context) => GesturePropProvider.empty()),
ChangeNotifierProvider(create: (context) => LocalSolutionsProvider(),lazy: false),
ChangeNotifierProvider(create: (context) => LocalSchemesProvider(),lazy: false),
],
child: Column(
mainAxisSize: MainAxisSize.max,

@ -1,8 +1,9 @@
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_solutions_provider.dart';
import 'package:dde_gesture_manager/models/solution.provider.dart';
import 'package:dde_gesture_manager/models/local_schemes_provider.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';
import 'package:flutter/animation.dart';
import 'package:flutter/cupertino.dart';
@ -21,25 +22,28 @@ class LocalManager extends StatefulWidget {
class _LocalManagerState extends State<LocalManager> {
late ScrollController _scrollController;
int? _hoveringIndex;
int? _selectedIndex;
late int _selectedIndex;
@override
void initState() {
super.initState();
/// todo: load from sp
_selectedIndex = 0;
_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;
if (index == _selectedIndex) _color = context.read<SettingsProvider>().currentActiveColor;
return _color;
}
@override
Widget build(BuildContext context) {
var isOpen = context.watch<ContentLayoutProvider>().localManagerOpened == true;
var localSolutions = context.watch<LocalSolutionsProvider>().solutions ?? [];
var localSchemes = context.watch<LocalSchemesProvider>().schemes ?? [];
return AnimatedContainer(
duration: mediumDuration,
curve: Curves.easeInOut,
@ -83,20 +87,27 @@ class _LocalManagerState extends State<LocalManager> {
],
),
Flexible(
child: Padding(
padding: EdgeInsets.only(top: 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 1, vertical: 2),
child: ListView.builder(
controller: _scrollController,
itemBuilder: (context, index) => GestureDetector(
onDoubleTap: () {
context.read<SolutionProvider>().copyFrom(localSolutions[index].solution);
setState(() {
_selectedIndex = index;
});
},
onTap: () {
context.read<SchemeProvider>().copyFrom(localSchemes[index].scheme);
setState(() {
_selectedIndex = index;
});
@ -111,11 +122,15 @@ class _LocalManagerState extends State<LocalManager> {
child: Container(
color: _getItemBackgroundColor(index),
child: Padding(
padding: const EdgeInsets.only(right: 12.0),
padding: const EdgeInsets.only(left: 6, right: 12.0),
child: DefaultTextStyle(
style: context.t.textTheme.bodyText2!.copyWith(
color: _selectedIndex == index ? Colors.white : null,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(localSolutions[index].solution.name ?? ''),
Text(localSchemes[index].scheme.name ?? ''),
Text('456'),
],
),
@ -123,16 +138,33 @@ class _LocalManagerState extends State<LocalManager> {
),
),
),
itemCount: localSolutions.length,
),
itemCount: localSchemes.length,
),
),
),
),
Container(height: 5),
Container(
height: 150,
color: Colors.black,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
DButton.add(enabled: true),
DButton.delete(enabled: _selectedIndex > 0),
DButton.duplicate(enabled: _selectedIndex > 0),
DButton.apply(enabled: _selectedIndex > 0),
]
.map((e) => Padding(
padding: const EdgeInsets.only(right: 4),
child: e,
))
.toList(),
),
),
],
),
),
),
],
),
),

@ -23,4 +23,15 @@ var darkTheme = ThemeData.dark().copyWith(
),
),
dialogBackgroundColor: Color(0xff202020),
tooltipTheme: ThemeData.dark().tooltipTheme.copyWith(
textStyle: TextStyle(
color: Colors.grey,
),
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Color(0xff282828).withOpacity(.9),
border: Border.all(color: Colors.black38),
),
),
);

@ -23,4 +23,15 @@ var lightTheme = ThemeData.light().copyWith(
),
),
dialogBackgroundColor: Color(0xfffefefe),
tooltipTheme: ThemeData.dark().tooltipTheme.copyWith(
textStyle: TextStyle(
color: Colors.grey.shade600,
),
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Color(0xfff8f8f8).withOpacity(.9),
border: Border.all(color: Colors.grey.shade400),
),
),
);

@ -1,5 +1,5 @@
import 'package:dde_gesture_manager/models/content_layout.provider.dart';
import 'package:dde_gesture_manager/models/solution.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';
@ -97,6 +97,14 @@ class H {
'commandline': GestureType.commandline,
}[typeName] ??
GestureType.built_in;
static Color? parseQtActiveColor(String? inp) {
if (inp == null) return null;
var list = inp.split(',');
if (list.length != 4) return null;
var rgba = list.map<int>((e) => int.parse(e) ~/ 257).toList();
return Color.fromARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
}
}
class PreferredPanelsStatus {

@ -18,8 +18,11 @@ Future<void> initEvents(BuildContext context) async {
} else {
var xsettings = GSettings('com.deepin.xsettings');
String? themeName;
Color? activeColor;
try {
themeName = (await xsettings.get('theme-name')).toString();
var _activeColor = (await xsettings.get('qt-active-color'));
activeColor = H.parseQtActiveColor(_activeColor.toNative());
} catch (e) {
print(e);
context.read<SettingsProvider>().setProps(isDarkMode: false);
@ -27,10 +30,14 @@ Future<void> initEvents(BuildContext context) async {
if (themeName != null) {
context.read<SettingsProvider>().setProps(isDarkMode: themeName.contains('dark'));
context.read<SettingsProvider>().setProps(activeColor: activeColor);
xsettings.keysChanged.listen((event) {
xsettings.get('theme-name').then((value) {
context.read<SettingsProvider>().setProps(isDarkMode: value.toString().contains('dark'));
});
xsettings.get('qt-active-color').then((value) {
context.read<SettingsProvider>().setProps(activeColor: H.parseQtActiveColor(value.toNative()));
});
});
}
}

@ -0,0 +1,405 @@
import 'package:collection/collection.dart';
const KeysOrder = [
'Ctrl',
'Super',
'Alt',
'Shift',
'Return',
'Escape',
'BackSpace',
'Tab',
'space',
'',
'',
'',
'',
'Print',
'ScrollLock',
'Pause',
'Insert',
'Home',
'Page_Up',
'Delete',
'End',
'Page_Down',
'F1',
'F2',
'F3',
'F4',
'F5',
'F6',
'F7',
'F8',
'F9',
'F10',
'F11',
'F12',
'-',
'=',
'(',
')',
r'\',
';',
"'",
'`',
',',
'.',
'/',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'0',
];
class KeyNames implements Comparable {
final String displayName;
final String realName;
const KeyNames({required this.displayName, required this.realName});
@override
int compareTo(other) => KeysOrder.indexOf(this.displayName) - KeysOrder.indexOf(other.displayName);
@override
String toString() => realName;
}
KeyNames? getPhysicalKeyNames(int keyId) => _knownPhysicalKeyNames[keyId];
KeyNames? getPhysicalKeyNamesByRealName(String name) =>
_knownPhysicalKeyNames.values.firstWhereOrNull((element) => element.realName == name);
/// https://www.w3.org/TR/uievents-code/
const Map<int, KeyNames> _knownPhysicalKeyNames = <int, KeyNames>{
/// https://www.w3.org/TR/uievents-code/#key-legacy
/*0x00000010: hyper,
0x00000011: superKey,
0x00000016: turbo,
0x0007009b: abort,
0x00000015: resume,
0x00000014: suspend,
0x00070079: again,
0x0007007c: copy,
0x0007007b: cut,
0x0007007e: find,
0x00070074: open,
0x0007007d: paste,
0x000700a3: props,
0x00070077: select,
0x0007007a: undo,*/
/// Often handled in hardware so that events aren't generated for this key.
/*0x00000012: fn,
0x00000013: fnLock,*/
/// W.T.F
/*0x00000017: privacyScreenToggle,
0x00010082: sleep,
0x00010083: wakeUp,
0x000100b5: displayToggleIntExt,
0x0005ff01: gameButton1,
0x0005ff02: gameButton2,
0x0005ff03: gameButton3,
0x0005ff04: gameButton4,
0x0005ff05: gameButton5,
0x0005ff06: gameButton6,
0x0005ff07: gameButton7,
0x0005ff08: gameButton8,
0x0005ff09: gameButton9,
0x0005ff0a: gameButton10,
0x0005ff0b: gameButton11,
0x0005ff0c: gameButton12,
0x0005ff0d: gameButton13,
0x0005ff0e: gameButton14,
0x0005ff0f: gameButton15,
0x0005ff10: gameButton16,
0x0005ff11: gameButtonA,
0x0005ff12: gameButtonB,
0x0005ff13: gameButtonC,
0x0005ff14: gameButtonLeft1,
0x0005ff15: gameButtonLeft2,
0x0005ff16: gameButtonMode,
0x0005ff17: gameButtonRight1,
0x0005ff18: gameButtonRight2,
0x0005ff19: gameButtonSelect,
0x0005ff1a: gameButtonStart,
0x0005ff1b: gameButtonThumbLeft,
0x0005ff1c: gameButtonThumbRight,
0x0005ff1d: gameButtonX,
0x0005ff1e: gameButtonY,
0x0005ff1f: gameButtonZ,
0x00070000: usbReserved,
0x00070001: usbErrorRollOver,
0x00070002: usbPostFail,
0x00070003: usbErrorUndefined,*/
0x00070004: const KeyNames(displayName: 'A', realName: 'a'),
0x00070005: const KeyNames(displayName: 'B', realName: 'b'),
0x00070006: const KeyNames(displayName: 'C', realName: 'c'),
0x00070007: const KeyNames(displayName: 'D', realName: 'd'),
0x00070008: const KeyNames(displayName: 'E', realName: 'e'),
0x00070009: const KeyNames(displayName: 'F', realName: 'f'),
0x0007000a: const KeyNames(displayName: 'G', realName: 'g'),
0x0007000b: const KeyNames(displayName: 'H', realName: 'h'),
0x0007000c: const KeyNames(displayName: 'I', realName: 'i'),
0x0007000d: const KeyNames(displayName: 'J', realName: 'j'),
0x0007000e: const KeyNames(displayName: 'K', realName: 'k'),
0x0007000f: const KeyNames(displayName: 'L', realName: 'l'),
0x00070010: const KeyNames(displayName: 'M', realName: 'm'),
0x00070011: const KeyNames(displayName: 'N', realName: 'n'),
0x00070012: const KeyNames(displayName: 'O', realName: 'o'),
0x00070013: const KeyNames(displayName: 'P', realName: 'p'),
0x00070014: const KeyNames(displayName: 'Q', realName: 'q'),
0x00070015: const KeyNames(displayName: 'R', realName: 'r'),
0x00070016: const KeyNames(displayName: 'S', realName: 's'),
0x00070017: const KeyNames(displayName: 'T', realName: 't'),
0x00070018: const KeyNames(displayName: 'U', realName: 'u'),
0x00070019: const KeyNames(displayName: 'V', realName: 'v'),
0x0007001a: const KeyNames(displayName: 'W', realName: 'w'),
0x0007001b: const KeyNames(displayName: 'X', realName: 'x'),
0x0007001c: const KeyNames(displayName: 'Y', realName: 'y'),
0x0007001d: const KeyNames(displayName: 'Z', realName: 'z'),
0x0007001e: const KeyNames(displayName: '1', realName: '1'),
0x0007001f: const KeyNames(displayName: '2', realName: '2'),
0x00070020: const KeyNames(displayName: '3', realName: '3'),
0x00070021: const KeyNames(displayName: '4', realName: '4'),
0x00070022: const KeyNames(displayName: '5', realName: '5'),
0x00070023: const KeyNames(displayName: '6', realName: '6'),
0x00070024: const KeyNames(displayName: '7', realName: '7'),
0x00070025: const KeyNames(displayName: '8', realName: '8'),
0x00070026: const KeyNames(displayName: '9', realName: '9'),
0x00070027: const KeyNames(displayName: '0', realName: '0'),
0x00070028: const KeyNames(displayName: 'Return', realName: 'Return'),
0x00070029: const KeyNames(displayName: 'Escape', realName: 'Escape'),
0x0007002a: const KeyNames(displayName: 'BackSpace', realName: 'BackSpace'),
0x0007002b: const KeyNames(displayName: 'Tab', realName: 'Tab'),
0x0007002c: const KeyNames(displayName: 'space', realName: 'space'),
0x0007002d: const KeyNames(displayName: '-', realName: 'minus'),
0x0007002e: const KeyNames(displayName: '=', realName: 'equal'),
0x0007002f: const KeyNames(displayName: '(', realName: 'parenleft'),
0x00070030: const KeyNames(displayName: ')', realName: 'parenright'),
0x00070031: const KeyNames(displayName: r'\', realName: 'backslash'),
0x00070033: const KeyNames(displayName: ';', realName: 'semicolon'),
0x00070034: const KeyNames(displayName: "'", realName: 'apostrophe'),
0x00070035: const KeyNames(displayName: '`', realName: 'grave'),
0x00070036: const KeyNames(displayName: ',', realName: 'comma'),
0x00070037: const KeyNames(displayName: '.', realName: 'period'),
0x00070038: const KeyNames(displayName: '/', realName: 'slash'),
0x00070039: const KeyNames(displayName: 'CapsLock', realName: 'Caps_Lock'),
0x0007003a: const KeyNames(displayName: 'F1', realName: 'F1'),
0x0007003b: const KeyNames(displayName: 'F2', realName: 'F2'),
0x0007003c: const KeyNames(displayName: 'F3', realName: 'F3'),
0x0007003d: const KeyNames(displayName: 'F4', realName: 'F4'),
0x0007003e: const KeyNames(displayName: 'F5', realName: 'F5'),
0x0007003f: const KeyNames(displayName: 'F6', realName: 'F6'),
0x00070040: const KeyNames(displayName: 'F7', realName: 'F7'),
0x00070041: const KeyNames(displayName: 'F8', realName: 'F8'),
0x00070042: const KeyNames(displayName: 'F9', realName: 'F9'),
0x00070043: const KeyNames(displayName: 'F10', realName: 'F10'),
0x00070044: const KeyNames(displayName: 'F11', realName: 'F11'),
0x00070045: const KeyNames(displayName: 'F12', realName: 'F12'),
0x00070046: const KeyNames(displayName: 'Print', realName: 'Print'),
0x00070047: const KeyNames(displayName: 'ScrollLock', realName: 'Scroll_Lock'),
0x00070048: const KeyNames(displayName: 'Pause', realName: 'Pause'),
0x00070049: const KeyNames(displayName: 'Insert', realName: 'Insert'),
0x0007004a: const KeyNames(displayName: 'Home', realName: 'Home'),
0x0007004b: const KeyNames(displayName: 'Page_Up', realName: 'Page_Up'),
0x0007004c: const KeyNames(displayName: 'Delete', realName: 'Delete'),
0x0007004d: const KeyNames(displayName: 'End', realName: 'End'),
0x0007004e: const KeyNames(displayName: 'Page_Down', realName: 'Page_Down'),
0x0007004f: const KeyNames(displayName: '', realName: 'Right'),
0x00070050: const KeyNames(displayName: '', realName: 'Left'),
0x00070051: const KeyNames(displayName: '', realName: 'Down'),
0x00070052: const KeyNames(displayName: '', realName: 'Up'),
0x00070053: const KeyNames(displayName: 'NumLock', realName: 'Num_Lock'),
0x00070054: const KeyNames(displayName: 'KP_Divide', realName: 'KP_Divide'),
0x00070055: const KeyNames(displayName: 'KP_Multiply', realName: 'KP_Multiply'),
0x00070056: const KeyNames(displayName: 'KP_Subtract', realName: 'KP_Subtract'),
0x00070057: const KeyNames(displayName: 'KP_Add', realName: 'KP_Add'),
0x00070058: const KeyNames(displayName: 'KP_Enter', realName: 'KP_Enter'),
0x00070059: const KeyNames(displayName: 'KP_1', realName: 'KP_1'),
0x0007005a: const KeyNames(displayName: 'KP_2', realName: 'KP_2'),
0x0007005b: const KeyNames(displayName: 'KP_3', realName: 'KP_3'),
0x0007005c: const KeyNames(displayName: 'KP_4', realName: 'KP_4'),
0x0007005d: const KeyNames(displayName: 'KP_5', realName: 'KP_5'),
0x0007005e: const KeyNames(displayName: 'KP_6', realName: 'KP_6'),
0x0007005f: const KeyNames(displayName: 'KP_7', realName: 'KP_7'),
0x00070060: const KeyNames(displayName: 'KP_8', realName: 'KP_8'),
0x00070061: const KeyNames(displayName: 'KP_9', realName: 'KP_9'),
0x00070062: const KeyNames(displayName: 'KP_0', realName: 'KP_0'),
0x00070063: const KeyNames(displayName: '.', realName: 'KP_Decimal'),
/// IntlBackslash ???
0x00070064: const KeyNames(displayName: r'\', realName: 'backslash'),
0x00070065: const KeyNames(displayName: 'Menu', realName: 'Menu'),
/// Mac only
// 0x00070066: power,
0x00070067: const KeyNames(displayName: 'KP_Equal', realName: 'KP_Equal'),
0x00070068: const KeyNames(displayName: 'F13', realName: 'F13'),
0x00070069: const KeyNames(displayName: 'F14', realName: 'F14'),
0x0007006a: const KeyNames(displayName: 'F15', realName: 'F15'),
0x0007006b: const KeyNames(displayName: 'F16', realName: 'F16'),
0x0007006c: const KeyNames(displayName: 'F17', realName: 'F17'),
0x0007006d: const KeyNames(displayName: 'F18', realName: 'F18'),
0x0007006e: const KeyNames(displayName: 'F19', realName: 'F19'),
0x0007006f: const KeyNames(displayName: 'F20', realName: 'F20'),
0x00070070: const KeyNames(displayName: 'F21', realName: 'F21'),
0x00070071: const KeyNames(displayName: 'F22', realName: 'F22'),
0x00070072: const KeyNames(displayName: 'F23', realName: 'F23'),
0x00070073: const KeyNames(displayName: 'F24', realName: 'F24'),
/// Not present on standard PC keyboards.
// 0x00070075: help,
0x0007007f: const KeyNames(displayName: 'XF86AudioMute', realName: 'XF86AudioMute'),
0x00070080: const KeyNames(displayName: 'XF86AudioRaiseVolume', realName: 'XF86AudioRaiseVolume'),
0x00070081: const KeyNames(displayName: 'XF86AudioLowerVolume', realName: 'XF86AudioLowerVolume'),
0x00070085: const KeyNames(displayName: 'KP_Separator', realName: 'KP_Separator'),
0x00070087: const KeyNames(displayName: 'KanaRo', realName: 'kana_RO'),
0x00070088: const KeyNames(displayName: 'Hiragana_Katakana', realName: 'Hiragana_Katakana'),
0x00070089: const KeyNames(displayName: 'yen', realName: 'yen'),
0x0007008a: const KeyNames(displayName: 'Henkan_Mode', realName: 'Henkan_Mode'),
0x0007008b: const KeyNames(displayName: 'Muhenkan', realName: 'Muhenkan'),
0x00070090: const KeyNames(displayName: 'Hangul', realName: 'Hangul'),
0x00070091: const KeyNames(displayName: 'Hangul_Hanja', realName: 'Hangul_Hanja'),
0x00070092: const KeyNames(displayName: 'Katakana', realName: 'Katakana'),
0x00070093: const KeyNames(displayName: 'Hiragana', realName: 'Hiragana'),
0x00070094: const KeyNames(displayName: 'Zenkaku', realName: 'Zenkaku'),
0x000700b6: const KeyNames(displayName: 'KP_Left', realName: 'KP_Left'),
0x000700b7: const KeyNames(displayName: 'KP_Right', realName: 'KP_Right'),
/// Found on the Microsoft Natural Keyboard.
// 0x000700bb: numpadBackspace,
/// W.T.F ???
/*0x000700d0: numpadMemoryStore,
0x000700d1: numpadMemoryRecall,
0x000700d2: numpadMemoryClear,
0x000700d3: numpadMemoryAdd,
0x000700d4: numpadMemorySubtract,
0x000700d7: numpadSignChange,
0x000700d9: numpadClearEntry,*/
0x000700d8: const KeyNames(displayName: 'NumLock', realName: 'Num_Lock'),
0x000700e0: const KeyNames(displayName: 'Ctrl', realName: 'Control_L'),
0x000700e1: const KeyNames(displayName: 'Shift', realName: 'Shift_L'),
0x000700e2: const KeyNames(displayName: 'Alt', realName: 'Alt_L'),
0x000700e3: const KeyNames(displayName: 'Super', realName: 'Super_L'),
0x000700e4: const KeyNames(displayName: 'Ctrl', realName: 'Control_R'),
0x000700e5: const KeyNames(displayName: 'Shift', realName: 'Shift_R'),
0x000700e6: const KeyNames(displayName: 'Alt', realName: 'Alt_R'),
0x000700e7: const KeyNames(displayName: 'Super', realName: 'Super_R'),
/// Toggles the display of information about the currently selected content, program, or media.
// 0x000c0060: info,
/// Toggles closed captioning on and off.
// 0x000c0061: closedCaptionToggle,
/// Too dangerous ...
/*0x000c006f: brightnessUp,
0x000c0070: brightnessDown,
0x000c0072: brightnessToggle,
0x000c0073: brightnessMinimum,
0x000c0074: brightnessMaximum,
0x000c0075: brightnessAuto,*/
/// seems only works on mobile.
/*0x000c0079: kbdIllumUp,
0x000c007a: kbdIllumDown,
0x000c0083: mediaLast,
0x000c008c: launchPhone,
0x000c008d: programGuide,
0x000c0094: exit,
0x000c009c: channelUp,
0x000c009d: channelDown,
0x000c00b0: mediaPlay,
0x000c00b1: mediaPause,
0x000c00b2: mediaRecord,
0x000c00b3: mediaFastForward,
0x000c00b4: mediaRewind,
0x000c00b5: mediaTrackNext,
0x000c00b6: mediaTrackPrevious,
0x000c00b7: mediaStop,
/// Mac only
// 0x000c00b8: eject,
0x000c00cd: mediaPlayPause,
0x000c00cf: speechInputToggle,
0x000c00e5: bassBoost,
0x000c0183: mediaSelect,*/
0x000c0184: const KeyNames(displayName: 'XF86Word', realName: 'XF86Word'),
0x000c0186: const KeyNames(displayName: 'XF86Excel', realName: 'XF86Excel'),
0x000c018a: const KeyNames(displayName: 'XF86Mail', realName: 'XF86Mail'),
/// not implements on linux.
// 0x000c018d: launchContacts,
0x000c018e: const KeyNames(displayName: 'XF86Calendar', realName: 'XF86Calendar'),
0x000c0192: const KeyNames(displayName: 'XF86Launch2', realName: 'XF86Launch2'),
0x000c0194: const KeyNames(displayName: 'XF86Launch1', realName: 'XF86Launch1'),
/// I don't think need implement those keys
/*0x000c0196: launchInternetBrowser,
0x000c019c: logOff,
0x000c019e: lockScreen,
0x000c019f: launchControlPanel,
0x000c01a2: selectTask,
0x000c01a7: launchDocuments,
0x000c01ab: spellCheck,
0x000c01ae: launchKeyboardLayout,
0x000c01b1: launchScreenSaver,
0x000c01b7: launchAudioBrowser,
0x000c01cb: launchAssistant,
0x000c0201: newKey,
0x000c0203: close,
0x000c0207: save,
0x000c0208: print,
0x000c0221: browserSearch,
0x000c0223: browserHome,
0x000c0224: browserBack,
0x000c0225: browserForward,
0x000c0226: browserStop,
0x000c0227: browserRefresh,
0x000c022a: browserFavorites,
0x000c022d: zoomIn,
0x000c022e: zoomOut,
0x000c0232: zoomToggle,
0x000c0279: redo,
0x000c0289: mailReply,
0x000c028b: mailForward,
0x000c028c: mailSend,
0x000c029d: keyboardLayoutSelect,
0x000c029f: showAllWindows,*/
};

@ -1,4 +1,6 @@
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:glass_kit/glass_kit.dart';
@ -7,6 +9,8 @@ class DButton extends StatefulWidget {
final double height;
final Widget child;
final GestureTapCallback? onTap;
final EdgeInsets? padding;
final Color? activeBorderColor;
const DButton({
Key? key,
@ -14,8 +18,94 @@ class DButton extends StatefulWidget {
this.height = defaultButtonHeight,
required this.child,
this.onTap,
this.padding,
this.activeBorderColor,
}) : super(key: key);
factory DButton.add({
Key? key,
required enabled,
GestureTapCallback? onTap,
height = defaultButtonHeight * .7,
width = defaultButtonHeight * .7,
}) =>
DButton(
key: key,
width: width,
height: height,
onTap: onTap,
child: Tooltip(
child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.add, size: 18)),
message: LocaleKeys.operation_add.tr(),
));
factory DButton.delete({
Key? key,
required enabled,
GestureTapCallback? onTap,
height = defaultButtonHeight * .7,
width = defaultButtonHeight * .7,
}) =>
DButton(
key: key,
width: width,
height: height,
onTap: onTap,
child: Tooltip(
child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.remove, size: 18)),
message: LocaleKeys.operation_delete.tr(),
));
factory DButton.apply({
Key? key,
required enabled,
GestureTapCallback? onTap,
height = defaultButtonHeight * .7,
width = defaultButtonHeight * .7,
}) =>
DButton(
key: key,
width: width,
height: height,
onTap: onTap,
child: Tooltip(
child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.check, size: 18)),
message: LocaleKeys.operation_apply.tr(),
));
factory DButton.duplicate({
Key? key,
required enabled,
GestureTapCallback? onTap,
height = defaultButtonHeight * .7,
width = defaultButtonHeight * .7,
}) =>
DButton(
key: key,
width: width,
height: height,
onTap: onTap,
child: Tooltip(
child: Opacity(opacity: enabled ? 1 : 0.4, child: const Icon(Icons.copy_rounded, size: 18)),
message: LocaleKeys.operation_duplicate.tr(),
));
factory DButton.dropdown({
Key? key,
width = 60.0,
height = kMinInteractiveDimension * .86,
padding: const EdgeInsets.only(left: 15),
required enabled,
required DropdownButton child,
}) =>
DButton(
key: key,
width: width,
height: height,
padding: padding,
child: child,
);
@override
State<DButton> createState() => _DButtonState();
}
@ -26,8 +116,9 @@ class _DButtonState extends State<DButton> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTap,
onTap: widget.child is DropdownButton ? (widget.child as DropdownButton).onTap : widget.onTap,
child: GlassContainer(
padding: widget.padding,
width: widget.width,
height: widget.height,
gradient: LinearGradient(
@ -35,8 +126,10 @@ class _DButtonState extends State<DButton> {
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderColor: Color(0xff565656),
borderWidth: 1,
borderColor: _hovering
? (widget.activeBorderColor ?? context.watch<SettingsProvider>().currentActiveColor)
: Color(0xff565656),
borderWidth: 2,
borderRadius: BorderRadius.circular(defaultBorderRadius),
child: MouseRegion(
onEnter: (event) => setState(() {

@ -420,6 +420,7 @@ class DDataCell {
/// * <https://material.io/design/components/data-tables.html>
class DDataTable extends StatefulWidget {
final Color headerBackgroundColor;
final ScrollController verticalScrollController;
/// Creates a widget describing a data table.
///
@ -466,6 +467,7 @@ class DDataTable extends StatefulWidget {
required this.rows,
this.checkboxHorizontalMargin,
required this.headerBackgroundColor,
required this.verticalScrollController,
}) : assert(columns != null),
assert(columns.isNotEmpty),
assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)),
@ -755,7 +757,7 @@ class _DDataTableState extends State<DDataTable> {
textDirection: numeric ? TextDirection.rtl : null,
mainAxisAlignment: center ? MainAxisAlignment.spaceAround : MainAxisAlignment.start,
children: <Widget>[
label,
Flexible(child: label),
if (onSort != null) ...<Widget>[
_SortArrow(
visible: sorted,
@ -1033,6 +1035,7 @@ class _DDataTableState extends State<DDataTable> {
padding: EdgeInsets.only(top: _headersRect?.last.height ?? 0),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: widget.verticalScrollController,
child: Transform.translate(
offset: Offset(0, -(_headersRect?.last.height ?? 0)),
child: Table(

@ -1,13 +1,14 @@
import 'package:collection/collection.dart';
import 'package:dde_gesture_manager/constants/sp_keys.dart';
import 'package:dde_gesture_manager/constants/supported_locales.dart';
import 'package:dde_gesture_manager/extensions.dart';
import 'package:dde_gesture_manager/generated/codegen_loader.g.dart';
import 'package:dde_gesture_manager/generated/locale_keys.g.dart';
import 'package:dde_gesture_manager/models/local_schemes_provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
import 'package:easy_localization/src/translations.dart';
class LanguageSwitcher extends StatelessWidget {
const LanguageSwitcher({Key? key}) : super(key: key);
@ -15,7 +16,7 @@ class LanguageSwitcher extends StatelessWidget {
@override
Widget build(BuildContext context) {
var _locale = EasyLocalization.of(context)?.currentLocale;
var _supportedLocale = supportedLocales.firstWhereOrNull((element) => element == _locale);
var _supportedLocale = getSupportedLocale(_locale) ?? SupportedLocale.zh_CN;
return PopupMenuButton<SupportedLocale>(
tooltip: LocaleKeys.language_tip.tr(),
@ -28,23 +29,29 @@ class LanguageSwitcher extends StatelessWidget {
),
],
),
itemBuilder: (BuildContext context) => supportedLocales
.map(
(locale) => PopupMenuItem(
value: SupportedLocale.zh_CN,
child: ListTile(
leading: Visibility(
child: Icon(CupertinoIcons.check_mark),
visible: _supportedLocale == locale,
),
title: Text(supportedLocaleNames[SupportedLocale.values[supportedLocales.indexOf(locale)]] ?? ''),
),
onTap: () {
EasyLocalization.of(context)?.setLocale(locale).then((_) {
if (!kIsWeb) WindowManager.instance.setTitle(LocaleKeys.app_name.tr());
initialValue: _supportedLocale,
onSelected: (value) {
EasyLocalization.of(context)?.setLocale(transformSupportedLocale(value)).then((_) {
var localeMap = Translations(CodegenLoader.mapLocales[context.locale.toString()]!);
if (!kIsWeb) WindowManager.instance.setTitle(localeMap.get(LocaleKeys.app_name)!);
var localSchemesProvider = context.read<LocalSchemesProvider>();
var schemes = localSchemesProvider.schemes!;
var newSchemes = [
schemes.first
..scheme.name = localeMap.get(LocaleKeys.local_manager_default_scheme_label)
..scheme.description = localeMap.get(LocaleKeys.local_manager_default_scheme_description),
...schemes.skip(1),
];
localSchemesProvider.setProps(schemes: newSchemes);
});
H().sp.setInt(SPKeys.userLanguage, supportedLocales.indexOf(locale));
H().sp.setInt(SPKeys.userLanguage, value.index);
},
itemBuilder: (BuildContext context) => SupportedLocale.values
.map(
(supportedLocale) => CheckedPopupMenuItem(
value: supportedLocale,
checked: EasyLocalization.of(context)?.locale == transformSupportedLocale(supportedLocale),
child: Text(supportedLocaleNames[supportedLocale] ?? ''),
),
)
.toList(),

@ -0,0 +1,128 @@
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:dde_gesture_manager/utils/keyboard_mapper.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TableCellShortcutListener extends StatefulWidget {
final double width;
final String initShortcut;
final Function(String shortcut) onComplete;
const TableCellShortcutListener({
Key? key,
this.width = 150.0,
required this.initShortcut,
required this.onComplete,
}) : super(key: key);
@override
_TableCellShortcutListenerState createState() => _TableCellShortcutListenerState();
}
class _TableCellShortcutListenerState extends State<TableCellShortcutListener> {
List<KeyNames> _shortcut = [];
bool inputMode = false;
FocusNode _focusNode = FocusNode();
_handleFocusChange() {
if (!_focusNode.hasFocus) {
widget.onComplete(_shortcut.join('+'));
}
}
_tryToAddKey(PhysicalKeyboardKey key) {
var names = getPhysicalKeyNames(key.usbHidUsage);
if (names != null && !_shortcut.contains(names))
setState(() {
_shortcut.add(names);
_shortcut.sort();
});
}
@override
void initState() {
var __shortcut = widget.initShortcut.split('+');
__shortcut.forEach((name) {
var keyNames = getPhysicalKeyNamesByRealName(name);
if (keyNames != null) _shortcut.add(keyNames);
});
_shortcut.sort();
_focusNode.addListener(_handleFocusChange);
super.initState();
}
@override
void dispose() {
_focusNode.removeListener(_handleFocusChange);
super.dispose();
}
@override
Widget build(BuildContext context) {
return RawKeyboardListener(
focusNode: _focusNode,
onKey: (evt) {
_tryToAddKey(evt.physicalKey);
},
child: GestureDetector(
onTap: () {
setState(() {
_shortcut = [];
inputMode = true;
});
},
child: Focus(
autofocus: true,
onKeyEvent: (_, __) => KeyEventResult.skipRemainingHandlers,
child: Container(
height: kMinInteractiveDimension * .86,
width: widget.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
color: Colors.grey.withOpacity(.3),
border: Border.all(
width: 2,
color: Focus.of(context).hasFocus
? context.watch<SettingsProvider>().activeColor ?? Color(0xff565656)
: Color(0xff565656)),
),
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: _shortcut
.map(
(e) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius / 2),
color: context.t.dialogBackgroundColor,
border: Border.all(width: 1, color: Color(0xff565656)),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: Text(
e.displayName.notNull ? e.displayName : LocaleKeys.str_null.tr(),
style: TextStyle(
color: context.watch<SettingsProvider>().activeColor,
),
),
),
),
),
)
.toList(),
),
),
),
),
),
),
);
}
}

@ -0,0 +1,75 @@
import 'package:dde_gesture_manager/constants/constants.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class TableCellTextField extends StatefulWidget {
final String? initText;
final String? hint;
final Function(String value) onComplete;
const TableCellTextField({
Key? key,
this.initText,
this.hint,
required this.onComplete,
}) : super(key: key);
@override
_TableCellTextFieldState createState() => _TableCellTextFieldState();
}
class _TableCellTextFieldState extends State<TableCellTextField> {
final FocusNode _focusNode = FocusNode(
onKeyEvent: (_, __) => KeyEventResult.skipRemainingHandlers,
);
final TextEditingController _controller = TextEditingController();
@override
void initState() {
_focusNode.addListener(_handleFocusChange);
_controller.text = widget.initText ?? '';
super.initState();
}
@override
void dispose() {
_focusNode.removeListener(_handleFocusChange);
super.dispose();
}
_handleFocusChange() {
if (!_focusNode.hasFocus) {
widget.onComplete(_controller.text);
}
}
@override
Widget build(BuildContext context) {
return Container(
height: kMinInteractiveDimension * .86,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
color: Colors.grey.withOpacity(.3),
border: Border.all(
width: 2,
color: Focus.of(context).hasFocus
? context.watch<SettingsProvider>().activeColor ??
Color(0xff565656)
: Color(0xff565656)),
),
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 15),
child: TextField(
focusNode: _focusNode,
cursorColor: context.watch<SettingsProvider>().activeColor,
decoration: InputDecoration.collapsed(hintText: widget.hint),
controller: _controller,
),
),
),
);
}
}

@ -11,7 +11,7 @@ class ThemeSwitcher extends StatelessWidget {
@override
Widget build(BuildContext context) {
var _brightnessMode = context.watch<ConfigsProvider>().brightnessMode;
return PopupMenuButton(
return PopupMenuButton<BrightnessMode>(
initialValue: _brightnessMode,
child: Row(
children: [
@ -23,35 +23,23 @@ class ThemeSwitcher extends StatelessWidget {
],
),
padding: EdgeInsets.zero,
onSelected: (value) => context.read<ConfigsProvider>().setProps(brightnessMode: value),
tooltip: LocaleKeys.theme_tip.tr(),
itemBuilder: (BuildContext context) => [
PopupMenuItem<BrightnessMode>(
child: ListTile(
leading: Visibility(
child: Icon(CupertinoIcons.check_mark),
visible: _brightnessMode == BrightnessMode.system,
),
title: Text(LocaleKeys.theme_system).tr(),
),
onTap: () => context.read<ConfigsProvider>().setProps(brightnessMode: BrightnessMode.system),
),
PopupMenuItem<BrightnessMode>(
child: ListTile(
leading: Visibility(
child: Icon(CupertinoIcons.check_mark),
visible: _brightnessMode == BrightnessMode.light,
),
title: Text(LocaleKeys.theme_light).tr()),
onTap: () => context.read<ConfigsProvider>().setProps(brightnessMode: BrightnessMode.light),
),
PopupMenuItem<BrightnessMode>(
child: ListTile(
leading: Visibility(
child: Icon(CupertinoIcons.check_mark),
visible: _brightnessMode == BrightnessMode.dark,
),
title: Text(LocaleKeys.theme_dark).tr()),
onTap: () => context.read<ConfigsProvider>().setProps(brightnessMode: BrightnessMode.dark),
CheckedPopupMenuItem<BrightnessMode>(
child: Text(LocaleKeys.theme_system).tr(),
checked: _brightnessMode == BrightnessMode.system,
value: BrightnessMode.system,
),
CheckedPopupMenuItem<BrightnessMode>(
child: Text(LocaleKeys.theme_light).tr(),
checked: _brightnessMode == BrightnessMode.light,
value: BrightnessMode.light,
),
CheckedPopupMenuItem<BrightnessMode>(
child: Text(LocaleKeys.theme_dark).tr(),
checked: _brightnessMode == BrightnessMode.dark,
value: BrightnessMode.dark,
),
],
);

@ -35,6 +35,8 @@ dependencies:
glass_kit: ^2.0.1
rect_getter: ^1.0.0
path_provider: ^2.0.5
uuid: ^3.0.5
adaptive_scrollbar: ^2.1.0
xdg_directories_web:
path: 3rd_party/xdg_directories_web

@ -20,13 +20,17 @@
"tip": "Display help documentation"
},
"market": {
"title": "Solution market"
"title": "Scheme market"
},
"local_manager": {
"title": "Local solution management"
"title": "Local scheme management",
"default_scheme": {
"label": "System default scheme",
"description": "System default gesture scheme, cannot be modified. (Secretly telling you that there is no actual content in this scheme, just when applying the scheme, it is achieved by deleting a custom configuration scheme."
}
},
"gesture_editor": {
"label": "Gesture program editing",
"label": "Gesture scheme editing",
"gesture": "gesture",
"direction": "direction",
"fingers": "fingers",
@ -58,5 +62,24 @@
"delete": "delete",
"duplicate": "duplicate",
"apply": "apply"
},
"str": {
"null": "Null"
},
"built_in_commands": {
"ShowWorkspace": "ShowWorkspace",
"Handle4Or5FingersSwipeUp": "4/5FingersSwipeUp",
"Handle4Or5FingersSwipeDown": "4/5FingersSwipeDown",
"ToggleMaximize": "ToggleMaximize",
"Minimize": "Minimize",
"ShowWindow": "ShowWindow",
"ShowAllWindow": "ShowAllWindow",
"SwitchApplication": "SwitchApplication",
"ReverseSwitchApplication": "ReverseSwitchApplication",
"SwitchWorkspace": "SwitchWorkspace",
"ReverseSwitchWorkspace": "ReverseSwitchWorkspace",
"SplitWindowLeft": "SplitWindowLeft",
"SplitWindowRight": "SplitWindowRight",
"MoveWindow": "MoveWindow"
}
}

@ -23,7 +23,11 @@
"title": "方案市场"
},
"local_manager": {
"title": "本地方案管理"
"title": "本地方案管理",
"default_scheme": {
"label": "系统默认方案",
"description": "系统默认的手势方案,不可修改。(偷偷告诉你,这个这个方案里没有任何实际内容,应用该方案时不过是通过删除自定义配置方案的方式来实现恢复系统默认方案~)"
}
},
"gesture_editor": {
"label": "手势方案编辑",
@ -58,5 +62,24 @@
"delete": "删除",
"duplicate": "复制",
"apply": "应用"
},
"str": {
"null": "无"
},
"built_in_commands": {
"ShowWorkspace": "显示工作区",
"Handle4Or5FingersSwipeUp": "4/5指向上划",
"Handle4Or5FingersSwipeDown": "4/5指向下划",
"ToggleMaximize": "全屏切换",
"Minimize": "最小化",
"ShowWindow": "显示桌面",
"ShowAllWindow": "查看所有窗口",
"SwitchApplication": "切换应用窗口",
"ReverseSwitchApplication": "反向切换应用窗口",
"SwitchWorkspace": "切换工作区",
"ReverseSwitchWorkspace": "反向切换工作区",
"SplitWindowLeft": "向左分屏",
"SplitWindowRight": "向右分屏",
"MoveWindow": "移动窗口"
}
}
Loading…
Cancel
Save