wip: gesture solution.

This commit is contained in:
2021-10-07 09:38:12 +08:00
parent 56c7262ba3
commit fbbbffe7af
13 changed files with 356 additions and 57 deletions
+11 -3
View File
@@ -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();
}
}
''';
'''
];
}
}
+2
View File
@@ -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());
}
+90
View File
@@ -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'];
}
}
+45 -26
View File
@@ -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(
+33 -11
View File
@@ -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(),
),
],
),
),
);
}
+1
View File
@@ -22,4 +22,5 @@ var darkTheme = ThemeData.dark().copyWith(
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
),
dialogBackgroundColor: Color(0xff202020),
);
+1
View File
@@ -22,4 +22,5 @@ var lightTheme = ThemeData.light().copyWith(
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
),
dialogBackgroundColor: Color(0xfffefefe),
);
+49
View File
@@ -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 {
+40 -17
View File
@@ -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