wip: gesture solution.

pull/2/head
DebuggerX 4 years ago
parent 56c7262ba3
commit fbbbffe7af

@ -0,0 +1,4 @@
root = true
[*.dart]
max_line_length = 120

@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Downloads WASM locally and use local fonts
# Temporary solution until https://github.com/flutter/flutter/issues/70101 and 77580 provide a better way
flutter clean
flutter build web
wasmLocation=$(grep canvaskit-wasm build/web/main.dart.js | sed -e 's/.*https/https/' -e 's/\/bin.*/\/bin/' | uniq)
echo "Downloading WASM from $wasmLocation"
curl -o build/web/canvaskit.js "$wasmLocation/canvaskit.js"
curl -o build/web/canvaskit.wasm "$wasmLocation/canvaskit.wasm"
sed -i -e "s!$wasmLocation!.!" \
-e "s!https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Me5WZLCzYlKw.ttf!./assets/packages/amos_mobile_widgets/assets/google_fonts/Roboto-Regular.ttf!" \
-e "s!https://fonts.googleapis.com/css2?family=Noto+Sans+Symbols!./assets/assets/css/Noto-Sans-Symbols.css!" \
-e "s!https://fonts.googleapis.com/css2?family=Noto+Color+Emoji+Compat!./assets/assets/css/Noto-Color-Emoji-Compat.css!" \
build/web/main.dart.js

@ -12,9 +12,13 @@ class AnnotationField {
}
class ProviderGenerator extends GeneratorForAnnotation<ProviderModel> {
var _preClassName;
@override
generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) {
var className = (element as ClassElement).source.shortName;
var needImports = className != _preClassName;
_preClassName = className;
List<AnnotationField> fields = [];
element.fields.forEach((field) {
var annotation = field.metadata.firstWhereOrNull(
@ -29,11 +33,14 @@ class ProviderGenerator extends GeneratorForAnnotation<ProviderModel> {
),
);
});
return '''
return [
if (needImports)
'''
import 'package:flutter/foundation.dart';
import 'package:dde_gesture_manager/extensions/compare_extension.dart';
import '$className';
''',
'''
class ${element.displayName}Provider extends ${element.displayName} with ChangeNotifier {
void setProps({
${fields.map((f) => '${f.type.endsWith('?') ? '' : 'required '}${f.type} ${f.name},').join('\n')}
@ -43,6 +50,7 @@ class ${element.displayName}Provider extends ${element.displayName} with ChangeN
if (changed) notifyListeners();
}
}
''';
'''
];
}
}

@ -5,6 +5,8 @@ extension SoutExtension on Object? {
return print(this);
case Null:
return print(null);
case List:
return print('[${(this as List).join(', ')}]');
default:
return print(this.toString());
}

@ -0,0 +1,90 @@
import 'dart:convert';
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
@ProviderModel()
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()
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.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,6 +1,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/solution.provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:dde_gesture_manager/widgets/dde_button.dart';
import 'package:dde_gesture_manager/widgets/dde_data_table.dart';
@ -13,6 +14,10 @@ class GestureEditor extends StatelessWidget {
@override
Widget build(BuildContext context) {
var layoutProvider = context.watch<ContentLayoutProvider>();
var solutionProvider = context.watch<SolutionProvider>();
solutionProvider.name.sout();
solutionProvider.gestures.sout();
return Flexible(
child: Padding(
padding: const EdgeInsets.all(10),
@ -22,7 +27,7 @@ class GestureEditor extends StatelessWidget {
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
@ -40,6 +45,13 @@ class GestureEditor extends StatelessWidget {
),
),
),
Text(
LocaleKeys.gesture_editor_label,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
).tr(),
Visibility(
visible: layoutProvider.marketOpened == false,
child: DButton(
@ -52,6 +64,7 @@ class GestureEditor extends StatelessWidget {
),
],
),
Container(height: 10),
Expanded(
child: Container(
decoration: BoxDecoration(
@ -72,6 +85,7 @@ class GestureEditor extends StatelessWidget {
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth),
child: DDataTable(
headerBackgroundColor: context.t.dialogBackgroundColor,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
border: Border.all(
@ -79,71 +93,76 @@ class GestureEditor extends StatelessWidget {
color: context.t.dividerColor,
),
),
dataRowColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered))
return Colors.blue;
return null;
}),
columns: [
DDataColumn(label: Text('gesture')),
DDataColumn(label: Text('direction')),
DDataColumn(label: Text('fingers')),
DDataColumn(label: Text('type')),
DDataColumn(label: Text('command')),
DDataColumn(label: Text('remark')),
DDataColumn(label: Text(LocaleKeys.gesture_editor_gesture.tr())),
DDataColumn(label: Text(LocaleKeys.gesture_editor_direction.tr())),
DDataColumn(label: Text(LocaleKeys.gesture_editor_fingers.tr())),
DDataColumn(label: Text(LocaleKeys.gesture_editor_type.tr())),
DDataColumn(label: Text(LocaleKeys.gesture_editor_command.tr())),
DDataColumn(label: Text(LocaleKeys.gesture_editor_remark.tr())),
],
rows: [
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('right')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_right).tr()),
DDataCell(Text('3')),
DDataCell(Text('shortcut')),
DDataCell(Text(LocaleKeys.gesture_editor_types_shortcut).tr()),
DDataCell(Text('ctrl+w')),
DDataCell(Text('close current page.')),
],
),
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('left')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_left).tr()),
DDataCell(Text('3')),
DDataCell(Text('shortcut')),
DDataCell(Text(LocaleKeys.gesture_editor_types_shortcut).tr()),
DDataCell(Text('ctrl+alt+t')),
DDataCell(Text('reopen last closed page.')),
],
),
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('left')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_left).tr()),
DDataCell(Text('3')),
DDataCell(Text('shortcut')),
DDataCell(Text(LocaleKeys.gesture_editor_types_shortcut).tr()),
DDataCell(Text('ctrl+alt+t')),
DDataCell(Text('reopen last closed page.')),
],
),
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('left')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_left).tr()),
DDataCell(Text('3')),
DDataCell(Text('shortcut')),
DDataCell(Text(LocaleKeys.gesture_editor_types_shortcut).tr()),
DDataCell(Text('ctrl+alt+t')),
DDataCell(Text('reopen last closed page.')),
],
),
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('left')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_left).tr()),
DDataCell(Text('3')),
DDataCell(Text('shortcut')),
DDataCell(Text(LocaleKeys.gesture_editor_types_shortcut).tr()),
DDataCell(Text('ctrl+alt+t')),
DDataCell(Text('reopen last closed page.')),
],
),
DDataRow(
cells: [
DDataCell(Text('swipe')),
DDataCell(Text('down')),
DDataCell(Text(LocaleKeys.gesture_editor_gestures_swipe).tr()),
DDataCell(Text(LocaleKeys.gesture_editor_directions_down).tr()),
DDataCell(Text('3')),
DDataCell(Text('commandline')),
DDataCell(Text(LocaleKeys.gesture_editor_types_commandline).tr()),
DDataCell(Text(
'dbus-send --type=method_call --dest=com.deepin.dde.Launcher /com/deepin/dde/Launcher com.deepin.dde.Launcher.Toggle')),
DDataCell(TextButton(
@ -162,7 +181,7 @@ class GestureEditor extends StatelessWidget {
),
Container(height: 10),
Container(
height: 400,
height: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(defaultBorderRadius),
border: Border.all(

@ -1,3 +1,5 @@
import 'package:dde_gesture_manager/extensions.dart';
import 'package:dde_gesture_manager/models/solution.provider.dart';
import 'package:dde_gesture_manager/pages/content.dart';
import 'package:dde_gesture_manager/pages/footer.dart';
import 'package:flutter/material.dart';
@ -13,18 +15,38 @@ class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Content(),
),
SizedBox(
height: 36,
child: Footer(),
),
body: MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => SolutionProvider.parse('''
{
"name": "test",
"desc": "some desc",
"gestures": [
{
"gesture": "swipe",
"direction": "up",
"fingers": 3,
"type": "shortcut",
"command": "ctrl+w"
}
]
}
''')),
// ChangeNotifierProvider(create: (context) => GesturePropProvider()),
],
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Content(),
),
SizedBox(
height: 36,
child: Footer(),
),
],
),
),
);
}

@ -22,4 +22,5 @@ var darkTheme = ThemeData.dark().copyWith(
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
),
dialogBackgroundColor: Color(0xff202020),
);

@ -22,4 +22,5 @@ var lightTheme = ThemeData.light().copyWith(
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
),
dialogBackgroundColor: Color(0xfffefefe),
);

@ -1,4 +1,5 @@
import 'package:dde_gesture_manager/models/content_layout.provider.dart';
import 'package:dde_gesture_manager/models/solution.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:dde_gesture_manager/constants/constants.dart';
@ -47,6 +48,54 @@ class H {
else
return preferredPanelsStatus..marketPanelOpened = false;
}
static String getGestureName(Gesture gesture) => const {
Gesture.swipe: 'swipe',
Gesture.tap: 'tap',
Gesture.pinch: 'pinch',
}[gesture]!;
static Gesture getGestureByName(String gestureName) =>
const {
'swipe': Gesture.swipe,
'tap': Gesture.tap,
'pinch': Gesture.pinch,
}[gestureName] ??
Gesture.swipe;
static String? getGestureDirectionName(GestureDirection direction) => const {
GestureDirection.up: 'up',
GestureDirection.down: 'down',
GestureDirection.left: 'left',
GestureDirection.right: 'right',
GestureDirection.pinch_in: 'in',
GestureDirection.pinch_out: 'out',
}[direction];
static GestureDirection getGestureDirectionByName(String? directionName) =>
const {
'up': GestureDirection.up,
'down': GestureDirection.down,
'left': GestureDirection.left,
'right': GestureDirection.right,
'in': GestureDirection.pinch_in,
'out': GestureDirection.pinch_out,
}[directionName] ??
GestureDirection.none;
static String getGestureTypeName(GestureType type) => const {
GestureType.built_in: 'built_in',
GestureType.shortcut: 'shortcut',
GestureType.commandline: 'commandline',
}[type]!;
static GestureType getGestureTypeByName(String typeName) =>
const {
'built_in': GestureType.built_in,
'shortcut': GestureType.shortcut,
'commandline': GestureType.commandline,
}[typeName] ??
GestureType.built_in;
}
class PreferredPanelsStatus {

@ -6,6 +6,7 @@
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
@ -415,6 +416,8 @@ class DDataCell {
/// provides controls for paging through the remainder of the data.
/// * <https://material.io/design/components/data-tables.html>
class DDataTable extends StatefulWidget {
final Color headerBackgroundColor;
/// Creates a widget describing a data table.
///
/// The [columns] argument must be a list of as many [DataColumn]
@ -459,6 +462,7 @@ class DDataTable extends StatefulWidget {
this.dividerThickness,
required this.rows,
this.checkboxHorizontalMargin,
required this.headerBackgroundColor,
}) : assert(columns != null),
assert(columns.isNotEmpty),
assert(sortColumnIndex == null || (sortColumnIndex >= 0 && sortColumnIndex < columns.length)),
@ -1078,29 +1082,29 @@ class _DDataTableState extends State<DDataTable> {
}
Future.microtask(() {
List<Rect> _rects = [];
var changed = false;
if (tableRows.first.children != null) {
for (var i = 0; i < tableRows.first.children!.length; i++) {
_rects.add((tableRows.first.children![i] as RectGetter).getRect() ?? Rect.zero);
if (!changed && (_headersRect == null || (_headersRect != null && _headersRect![i] != _rects[i]))) {
changed = true;
}
}
if (changed)
setState(() {
_headersRect = _rects;
});
}
_buildHeaderStack(tableRows);
});
var _skickyHeaders = [];
List<Widget> _skickyHeaders = [];
var _headerBackgroundHSLColor = HSLColor.fromColor(widget.headerBackgroundColor);
HSLColor.fromColor(widget.headerBackgroundColor).withSaturation(.1).toColor();
if (_headersRect != null && _headersRect!.length > 0) {
for (var i = 0; i < _headersRect!.length; i++) {
_skickyHeaders.add(Positioned(
child: Container(
color: Colors.deepPurple,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
_headerBackgroundHSLColor
.withLightness(
_headerBackgroundHSLColor.lightness - 0.1 < 0 ? 0 : _headerBackgroundHSLColor.lightness - 0.1)
.toColor(),
widget.headerBackgroundColor,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: (tableRows.first.children![i] as RectGetter).clone(),
),
left: _headersRect![i].left - _headersRect![0].left,
@ -1136,6 +1140,25 @@ class _DDataTableState extends State<DDataTable> {
),
);
}
void _buildHeaderStack(List<TableRow> tableRows) {
List<Rect> _rects = [];
var changed = false;
if (tableRows.first.children != null) {
for (var i = 0; i < tableRows.first.children!.length; i++) {
_rects.add((tableRows.first.children![i] as RectGetter).getRect() ?? Rect.zero);
if (!changed && (_headersRect == null || (_headersRect != null && _headersRect![i] != _rects[i]))) {
changed = true;
}
}
if (changed)
setState(() {
_headersRect = _rects;
});
}
if (_rects == null || _rects.isEmpty || _rects.first == null)
Future.microtask(() => _buildHeaderStack(tableRows));
}
}
/// A rectangular area of a Material that responds to touch but clips

@ -24,5 +24,38 @@
},
"local_manager": {
"title": "Local solution management"
},
"gesture_editor": {
"label": "Gesture program editing",
"gesture": "gesture",
"direction": "direction",
"fingers": "fingers",
"type": "type",
"command": "command",
"remark": "remark",
"directions": {
"up": "up",
"down": "down",
"left": "left",
"right": "right",
"in": "pinch-in",
"out": "pinch-out"
},
"gestures": {
"swipe": "swipe",
"pinch": "pinch",
"tap": "pinch"
},
"types": {
"built_in": "built-in",
"commandline": "commandline",
"shortcut": "shortcut"
}
},
"operation": {
"add": "Add",
"delete": "delete",
"duplicate": "duplicate",
"apply": "apply"
}
}

@ -24,5 +24,38 @@
},
"local_manager": {
"title": "本地方案管理"
},
"gesture_editor": {
"label": "手势方案编辑",
"gesture": "手势",
"direction": "方向",
"fingers": "手指数",
"type": "类型",
"command": "命令",
"remark": "备注",
"directions": {
"up": "向上",
"down": "向下",
"left": "向左",
"right": "向右",
"in": "向内捏合",
"out": "向外展开"
},
"gestures": {
"swipe": "滑动",
"pinch": "捏",
"tap": "点击"
},
"types": {
"built_in": "内置操作",
"commandline": "命令行",
"shortcut": "快捷键"
}
},
"operation": {
"add": "新增",
"delete": "删除",
"duplicate": "复制",
"apply": "应用"
}
}
Loading…
Cancel
Save