wip: add provider generator.

This commit is contained in:
2021-09-18 18:28:35 +08:00
parent 1efc737284
commit 9fa94e38a7
14 changed files with 228 additions and 78 deletions
+9
View File
@@ -0,0 +1,9 @@
class ProviderModel {
const ProviderModel();
}
class ProviderModelProp {
const ProviderModelProp({this.nullable = true});
final bool nullable;
}
+6
View File
@@ -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');
+48
View File
@@ -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;
}
+12
View File
@@ -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());
}
}
}
+26 -51
View File
@@ -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,
return 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,
children: <Widget>[
Positioned(key: bottomChildKey, child: bottomChild),
Positioned(key: topChildKey, child: topChild),
],
),
firstChild: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: isDarkMode == true ? Colors.blue : Colors.blue,
brightness: isDarkMode == true ? Brightness.dark : Brightness.light,
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),
),
);
},
);
+6 -16
View File
@@ -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;
}
+16 -1
View File
@@ -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();
}
}
+1
View File
@@ -0,0 +1 @@
export 'init_web.dart' if (dart.library.io) 'init_linux.dart';
+34
View File
@@ -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));
}
+13
View File
@@ -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();
}