wip: add provider generator.

pull/1/head
DebuggerX 4 years ago
parent 1efc737284
commit 9fa94e38a7

@ -1,16 +1,47 @@
# dde_gesture_manager
# DDE Gesture Manager
专为 DDE 桌面环境打造的触摸板手势管理工具
A new Flutter project.
## ProviderGenerator
利用 [source_gen](https://pub.dev/packages/source_gen) 和 [build_runner](https://pub.flutter-io.cn/packages/build_runner) 生成 [provider](https://pub.flutter-io.cn/packages/provider) 的模板代码:
1. 在 `lib/models/` 下编写模型类
```dart
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
## Getting Started
@ProviderModel()
class Test {
@ProviderModelProp()
bool? tested;
This project is a starting point for a Flutter application.
@ProviderModelProp()
String? name;
}
A few resources to get you started if this is your first Flutter project:
```
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
2. `app` 项目目录下执行 `flutter packages pub run build_runner build`
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
3. 将在 `lib/models/test.provider.dart` 生成如下代码:
```dart
import 'package:flutter/foundation.dart';
import 'package:dde_gesture_manager/extensions/compare_extension.dart';
import 'test.dart';
class TestProvider extends Test with ChangeNotifier {
void setProps({
bool? tested,
String? name,
}) {
bool changed = false;
if (tested.diff(this.tested)) {
this.tested = tested;
changed = true;
}
if (name.diff(this.name)) {
this.name = name;
changed = true;
}
if (changed) notifyListeners();
}
}
```

@ -0,0 +1,11 @@
builders:
provider_builder:
import: 'lib/builder/provider_builder.dart'
builder_factories: [ 'providerBuilder' ]
build_extensions: { '.dart': [ '.provider.dart' ] }
auto_apply: root_package
build_to: source
defaults:
generate_for:
include:
- lib/models/**

@ -0,0 +1,9 @@
class ProviderModel {
const ProviderModel();
}
class ProviderModelProp {
const ProviderModelProp({this.nullable = true});
final bool nullable;
}

@ -0,0 +1,6 @@
import 'package:dde_gesture_manager/builder/provider_generator.dart';
import 'package:source_gen/source_gen.dart';
import 'package:build/build.dart';
Builder providerBuilder(BuilderOptions options) =>
LibraryBuilder(ProviderGenerator(), generatedExtension: '.provider.dart');

@ -0,0 +1,48 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:build/src/builder/build_step.dart';
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
import 'package:source_gen/source_gen.dart';
import 'package:collection/collection.dart';
class AnnotationField {
String name;
String type;
AnnotationField(this.name, this.type);
}
class ProviderGenerator extends GeneratorForAnnotation<ProviderModel> {
@override
generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) {
var className = (element as ClassElement).source.shortName;
List<AnnotationField> fields = [];
element.fields.forEach((field) {
var annotation = field.metadata.firstWhereOrNull(
(m) => m.computeConstantValue()?.type?.getDisplayString(withNullability: true) == 'ProviderModelProp');
if (annotation != null)
fields.add(
AnnotationField(
field.displayName,
field.type.getDisplayString(
withNullability: annotation.computeConstantValue()?.getField('nullable')?.toBoolValue() ?? true,
),
),
);
});
return '''
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')}
}) {
bool changed = false;
${fields.map((f) => 'if (${f.name}.diff(this.${f.name})) {this.${f.name} = ${f.name}; changed = true; }').join('\n')}
if (changed) notifyListeners();
}
}
''';
}
}

@ -0,0 +1,3 @@
extension CompareExtension on Object? {
bool diff(other) => this != null && this != other;
}

@ -0,0 +1,12 @@
extension SoutExtension on Object? {
void sout() {
switch (this.runtimeType) {
case String:
return print(this);
case Null:
return print(null);
default:
return print(this.toString());
}
}
}

@ -1,29 +1,13 @@
import 'package:dde_gesture_manager/models/settings.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:dde_gesture_manager/utils/init.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:gsettings/gsettings.dart';
import 'package:provider/provider.dart';
import 'package:window_manager/window_manager.dart';
import 'package:xdg_directories/xdg_directories.dart' as xdgDir;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb) {
print(await xdgDir.configHome);
print(await xdgDir.cacheHome);
print(await xdgDir.dataHome);
print('------');
print(await xdgDir.configDirs.join('\n'));
print('------');
print(await xdgDir.dataDirs.join('\n'));
print('------');
print(await xdgDir.runtimeDir);
print('------');
var windowManager = WindowManager.instance;
windowManager.setTitle('Gesture Manager For DDE');
windowManager.setMinimumSize(const Size(800, 600));
}
await initConfigs();
runApp(MyApp());
}
@ -36,41 +20,32 @@ class MyApp extends StatelessWidget {
],
builder: (context, child) {
var isDarkMode = context.watch<SettingsProvider>().isDarkMode;
return AnimatedCrossFade(
crossFadeState: isDarkMode != null ? CrossFadeState.showFirst : CrossFadeState.showSecond,
alignment: Alignment.center,
layoutBuilder: (topChild, topChildKey, bottomChild, bottomChildKey) => Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: <Widget>[
Positioned(key: bottomChildKey, child: bottomChild),
Positioned(key: topChildKey, child: topChild),
],
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: isDarkMode == true ? Colors.blue : Colors.blue,
brightness: isDarkMode == true ? Brightness.dark : Brightness.light,
),
firstChild: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: isDarkMode == true ? Colors.blue : Colors.blue,
brightness: isDarkMode == true ? Brightness.dark : Brightness.light,
home: AnimatedCrossFade(
crossFadeState: isDarkMode != null ? CrossFadeState.showFirst : CrossFadeState.showSecond,
alignment: Alignment.center,
layoutBuilder: (topChild, topChildKey, bottomChild, bottomChildKey) => Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: <Widget>[
Positioned(key: bottomChildKey, child: bottomChild),
Positioned(key: topChildKey, child: topChild),
],
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
),
secondChild: Builder(builder: (_) {
var xsettings = GSettings('com.deepin.xsettings');
xsettings.get('theme-name').then((value) {
Future.delayed(
Duration(seconds: 1),
() => context.read<SettingsProvider>().setProps(isDarkMode: value.toString().contains('dark')),
firstChild: MyHomePage(title: 'Flutter Demo Home Page'),
secondChild: Builder(builder: (context) {
initEvents(context);
return Center(
child: CircularProgressIndicator(),
);
});
xsettings.keysChanged.listen((event) {
xsettings.get('theme-name').then((value) {
context.read<SettingsProvider>().setProps(isDarkMode: value.toString().contains('dark'));
});
});
return CircularProgressIndicator();
}),
duration: Duration(seconds: 1),
}),
duration: Duration(seconds: 1),
),
);
},
);

@ -1,20 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:dde_gesture_manager/builder/provider_annotation.dart';
@ProviderModel()
class Settings {
bool? _isDarkMode;
@ProviderModelProp()
bool? isDarkMode;
bool? get isDarkMode => _isDarkMode;
}
class SettingsProvider extends Settings with ChangeNotifier {
void setProps({
bool? isDarkMode,
}) {
bool changed = false;
if (this._isDarkMode != isDarkMode) {
this._isDarkMode = isDarkMode;
changed = true;
}
if (changed) notifyListeners();
}
@ProviderModelProp()
String? name;
}

@ -1,2 +1,17 @@
import 'package:shared_preferences/shared_preferences.dart';
class H {
}
H._();
static final _h = H._();
factory H() => _h;
late SharedPreferences _sp;
SharedPreferences get sp => _sp;
initSharedPreference() async {
_sp = await SharedPreferences.getInstance();
}
}

@ -0,0 +1 @@
export 'init_web.dart' if (dart.library.io) 'init_linux.dart';

@ -0,0 +1,34 @@
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gsettings/gsettings.dart';
import 'package:provider/provider.dart';
import 'package:window_manager/window_manager.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
Future<void> initEvents(BuildContext context) async {
var isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
if (isDark) {
context.read<SettingsProvider>().setProps(isDarkMode: isDark);
} else {
var xsettings = GSettings('com.deepin.xsettings');
xsettings.get('theme-name').then((value) {
Future.delayed(
Duration(seconds: 1),
() => context.read<SettingsProvider>().setProps(isDarkMode: value.toString().contains('dark')),
);
});
xsettings.keysChanged.listen((event) {
xsettings.get('theme-name').then((value) {
context.read<SettingsProvider>().setProps(isDarkMode: value.toString().contains('dark'));
});
});
}
}
Future<void> initConfigs() async {
await H().initSharedPreference();
var windowManager = WindowManager.instance;
windowManager.setTitle('Gesture Manager For DDE');
windowManager.setMinimumSize(const Size(800, 600));
}

@ -0,0 +1,13 @@
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
Future<void> initEvents(BuildContext context) async {
var isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
context.read<SettingsProvider>().setProps(isDarkMode: isDark);
}
Future<void> initConfigs() async {
await H().initSharedPreference();
}

@ -38,6 +38,8 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: 2.1.2
source_gen: 1.1.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

Loading…
Cancel
Save