pikapika/lib/basic/config/Themes.dart

444 lines
12 KiB
Dart
Raw Permalink Normal View History

2021-09-29 23:57:09 +00:00
/// 主题
import 'package:event/event.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2021-11-11 03:00:38 +00:00
import 'package:pikapika/basic/Common.dart';
2021-09-29 23:57:09 +00:00
import '../Method.dart';
2021-10-14 10:12:36 +00:00
import 'Platform.dart';
2021-09-29 23:57:09 +00:00
2021-10-21 04:08:51 +00:00
// 字体相关
2021-10-15 06:18:29 +00:00
const _fontFamilyProperty = "fontFamily";
String? _fontFamily;
Future initFont() async {
var defaultFont = "";
_fontFamily = await method.loadProperty(_fontFamilyProperty, defaultFont);
}
ThemeData _fontThemeData(bool dark) {
return ThemeData(
brightness: dark ? Brightness.dark : Brightness.light,
2021-10-20 06:52:05 +00:00
fontFamily: _fontFamily == "" ? null : _fontFamily,
2021-10-15 06:18:29 +00:00
);
}
Future<void> inputFont(BuildContext context) async {
var font = await displayTextInputDialog(
2022-03-23 10:51:38 +00:00
context,
src: "$_fontFamily",
title: "字体",
hint: "请输入字体",
desc:
"请输入字体的名称, 例如宋体/黑体, 如果您保存后没有发生变化, 说明字体无法使用或名称错误, 可以去参考C:\\Windows\\Fonts寻找您的字体。",
2021-10-15 06:18:29 +00:00
);
if (font != null) {
await method.saveProperty(_fontFamilyProperty, font);
_fontFamily = font;
2022-03-23 10:51:38 +00:00
_reloadTheme();
2021-10-15 06:18:29 +00:00
}
}
Widget fontSetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
2022-03-19 04:12:27 +00:00
title: const Text("字体"),
2021-10-15 06:18:29 +00:00
subtitle: Text("$_fontFamily"),
onTap: () async {
await inputFont(context);
setState(() {});
},
);
},
);
}
2021-10-21 04:08:51 +00:00
// 主题相关
2021-09-29 23:57:09 +00:00
// 主题包
abstract class _ThemePackage {
String code();
String name();
2021-10-15 06:18:29 +00:00
ThemeData themeData(ThemeData rawData);
2022-03-23 10:51:38 +00:00
bool isDark();
2021-09-29 23:57:09 +00:00
}
class _OriginTheme extends _ThemePackage {
@override
String code() => "origin";
@override
String name() => "原生";
@override
2021-10-15 06:18:29 +00:00
ThemeData themeData(ThemeData rawData) => rawData;
2022-03-23 10:51:38 +00:00
@override
bool isDark() => false;
2021-09-29 23:57:09 +00:00
}
class _PinkTheme extends _ThemePackage {
@override
String code() => "pink";
@override
String name() => "粉色";
@override
2022-03-23 10:51:38 +00:00
ThemeData themeData(ThemeData rawData) => rawData.copyWith(
2021-09-29 23:57:09 +00:00
brightness: Brightness.light,
colorScheme: ColorScheme.light(
secondary: Colors.pink.shade200,
),
appBarTheme: AppBarTheme(
2021-12-05 13:13:24 +00:00
systemOverlayStyle: SystemUiOverlayStyle.light,
2021-09-29 23:57:09 +00:00
color: Colors.pink.shade200,
2022-03-25 14:57:30 +00:00
iconTheme: const IconThemeData(
2021-09-29 23:57:09 +00:00
color: Colors.white,
),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
selectedItemColor: Colors.pink[300],
unselectedItemColor: Colors.grey[500],
),
dividerColor: Colors.grey.shade200,
2021-12-15 10:44:52 +00:00
primaryColor: Colors.pink.shade200,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.pink.shade200,
selectionColor: Colors.pink.shade300.withAlpha(150),
selectionHandleColor: Colors.pink.shade300.withAlpha(200),
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.pink.shade200),
),
),
2021-09-29 23:57:09 +00:00
);
2022-03-23 10:51:38 +00:00
@override
bool isDark() => false;
2021-09-29 23:57:09 +00:00
}
class _BlackTheme extends _ThemePackage {
@override
String code() => "black";
@override
String name() => "酷黑";
@override
2022-03-23 10:51:38 +00:00
ThemeData themeData(ThemeData rawData) => rawData.copyWith(
2021-09-29 23:57:09 +00:00
brightness: Brightness.light,
colorScheme: ColorScheme.light(
secondary: Colors.pink.shade200,
),
appBarTheme: AppBarTheme(
2021-12-05 13:13:24 +00:00
systemOverlayStyle: SystemUiOverlayStyle.light,
2021-09-29 23:57:09 +00:00
color: Colors.grey.shade800,
2022-03-25 14:57:30 +00:00
iconTheme: const IconThemeData(
2021-09-29 23:57:09 +00:00
color: Colors.white,
),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
selectedItemColor: Colors.white,
unselectedItemColor: Colors.grey[400],
backgroundColor: Colors.grey.shade800,
),
dividerColor: Colors.grey.shade200,
2021-12-15 10:44:52 +00:00
primaryColor: Colors.pink.shade200,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.pink.shade200,
selectionColor: Colors.pink.shade300.withAlpha(150),
selectionHandleColor: Colors.pink.shade300.withAlpha(200),
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.pink.shade200),
),
),
2021-09-29 23:57:09 +00:00
);
2022-03-23 10:51:38 +00:00
@override
bool isDark() => false;
2021-09-29 23:57:09 +00:00
}
class _DarkTheme extends _ThemePackage {
@override
String code() => "dark";
@override
String name() => "暗黑";
@override
2022-03-23 10:51:38 +00:00
ThemeData themeData(ThemeData rawData) => rawData.copyWith(
brightness: Brightness.dark,
2021-09-29 23:57:09 +00:00
colorScheme: ColorScheme.light(
secondary: Colors.pink.shade200,
),
2022-03-19 04:12:27 +00:00
appBarTheme: const AppBarTheme(
2021-12-05 13:13:24 +00:00
systemOverlayStyle: SystemUiOverlayStyle.light,
2021-09-29 23:57:09 +00:00
color: Color(0xFF1E1E1E),
foregroundColor: Colors.white,
2021-09-29 23:57:09 +00:00
iconTheme: IconThemeData(
color: Colors.white,
),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
selectedItemColor: Colors.white,
unselectedItemColor: Colors.grey.shade300,
backgroundColor: Colors.grey.shade900,
),
2021-12-15 10:44:52 +00:00
primaryColor: Colors.pink.shade200,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.pink.shade200,
selectionColor: Colors.pink.shade300.withAlpha(150),
selectionHandleColor: Colors.pink.shade300.withAlpha(200),
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.pink.shade200),
),
),
2021-09-29 23:57:09 +00:00
);
2022-03-23 10:51:38 +00:00
@override
bool isDark() => true;
2021-09-29 23:57:09 +00:00
}
class _DustyBlueTheme extends _ThemePackage {
@override
String code() => "dustyBlue";
@override
String name() => "灰蓝";
@override
2022-03-23 10:51:38 +00:00
ThemeData themeData(ThemeData rawData) => rawData.copyWith(
brightness: Brightness.dark,
2021-12-15 04:22:40 +00:00
scaffoldBackgroundColor: Color.alphaBlend(
2022-03-23 10:51:38 +00:00
const Color(0x11999999),
const Color(0xff20253b),
2022-03-19 04:12:27 +00:00
),
cardColor: Color.alphaBlend(
2022-03-23 10:51:38 +00:00
const Color(0x11AAAAAA),
const Color(0xff20253b),
2022-03-19 04:12:27 +00:00
),
colorScheme: ColorScheme.light(
secondary: Colors.blue.shade200,
),
2022-03-19 04:12:27 +00:00
appBarTheme: const AppBarTheme(
2021-12-05 13:13:24 +00:00
systemOverlayStyle: SystemUiOverlayStyle.light,
color: Color(0xff20253b),
foregroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.white,
),
),
2022-03-25 14:57:30 +00:00
dialogTheme: const DialogTheme(
2021-12-15 15:38:07 +00:00
backgroundColor: Color(0xff20253b),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
2022-03-25 14:57:30 +00:00
backgroundColor: const Color(0xff191b26),
selectedItemColor: Colors.blue.shade200,
unselectedItemColor: Colors.grey.shade500,
),
dividerColor: Colors.grey.shade800,
2021-12-15 10:44:52 +00:00
primaryColor: Colors.blue.shade200,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.blue.shade200,
selectionColor: Colors.blue.shade900,
selectionHandleColor: Colors.blue.shade800,
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue.shade500),
),
),
);
2022-03-23 10:51:38 +00:00
@override
bool isDark() => true;
}
2022-03-23 10:51:38 +00:00
class _DarkBlackTheme extends _ThemePackage {
@override
String code() => "dark_black";
@override
String name() => "纯黑";
@override
ThemeData themeData(ThemeData rawData) => rawData.copyWith(
brightness: Brightness.dark,
2022-03-23 10:51:38 +00:00
colorScheme: ColorScheme.light(
secondary: Colors.pink.shade200,
),
scaffoldBackgroundColor: Colors.black,
appBarTheme: const AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle.light,
color: Color.fromARGB(0xff, 10, 10, 10),
foregroundColor: Colors.white,
2022-03-23 10:51:38 +00:00
iconTheme: IconThemeData(
color: Colors.white,
),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
selectedItemColor: Colors.white,
unselectedItemColor: Colors.grey.shade300,
backgroundColor: const Color.fromARGB(0xff, 10, 10, 10),
),
primaryColor: Colors.pink.shade200,
textSelectionTheme: TextSelectionThemeData(
cursorColor: Colors.pink.shade200,
selectionColor: Colors.pink.shade300.withAlpha(150),
selectionHandleColor: Colors.pink.shade300.withAlpha(200),
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.pink.shade200),
),
),
dividerColor: const Color.fromARGB(0xff, 64, 64, 64),
);
@override
bool isDark() => true;
}
2021-09-29 23:57:09 +00:00
final _themePackages = <_ThemePackage>[
_OriginTheme(),
_PinkTheme(),
_BlackTheme(),
2022-03-23 10:51:38 +00:00
_DarkTheme(),
_DustyBlueTheme(),
_DarkBlackTheme(),
2021-09-29 23:57:09 +00:00
];
// 主题更换事件
var themeEvent = Event<EventArgs>();
2022-03-23 10:51:38 +00:00
const _nightModePropertyName = "androidNightMode";
const _lightThemePropertyName = "theme";
const _darkThemePropertyName = "theme.dark";
const _defaultLightThemeCode = "pink";
const _defaultDarkThemeCode = "dark";
bool androidNightModeDisplay = false;
bool androidNightMode = false;
String? _lightThemeCode;
ThemeData? _lightThemeData;
String? _darkThemeCode;
ThemeData? _darkThemeData;
2021-10-21 04:08:51 +00:00
2022-03-23 10:51:38 +00:00
// _changeThemeByCode
2021-09-29 23:57:09 +00:00
2022-03-23 10:51:38 +00:00
String _codeToName(String? code) {
2021-09-29 23:57:09 +00:00
for (var package in _themePackages) {
2022-03-23 10:51:38 +00:00
if (code == package.code()) {
2021-09-29 23:57:09 +00:00
return package.name();
}
}
return "";
}
2022-03-23 10:51:38 +00:00
String currentLightThemeName() {
return _codeToName(_lightThemeCode);
}
String currentDarkThemeName() {
return _codeToName(_darkThemeCode);
2021-10-15 06:18:29 +00:00
}
2022-03-23 10:51:38 +00:00
ThemeData? currentLightThemeData() {
return _lightThemeData;
}
ThemeData? currentDarkThemeData() {
return _darkThemeData;
2021-09-29 23:57:09 +00:00
}
// 根据Code选择主题, 并发送主题更换事件
2022-03-23 10:51:38 +00:00
ThemeData? _themeByCode(String? themeCode) {
2021-09-29 23:57:09 +00:00
for (var package in _themePackages) {
if (themeCode == package.code()) {
2022-03-23 10:51:38 +00:00
return package.themeData(_fontThemeData(package.isDark()));
2021-09-29 23:57:09 +00:00
}
}
2022-03-23 10:51:38 +00:00
return null;
}
void _reloadTheme() {
_lightThemeData = _themeByCode(_lightThemeCode);
if (androidNightMode) {
_darkThemeData = _themeByCode(_darkThemeCode);
} else {
_darkThemeData = _lightThemeData;
2021-10-15 06:18:29 +00:00
}
2021-09-29 23:57:09 +00:00
themeEvent.broadcast();
}
Future<dynamic> initTheme() async {
2022-03-23 10:51:38 +00:00
androidNightModeDisplay = androidVersion >= 29;
androidNightMode =
2021-10-15 06:18:29 +00:00
await method.loadProperty(_nightModePropertyName, "true") == "true";
2022-03-23 10:51:38 +00:00
_lightThemeCode = await method.loadProperty(
_lightThemePropertyName, _defaultLightThemeCode);
_darkThemeCode =
await method.loadProperty(_darkThemePropertyName, _defaultDarkThemeCode);
_reloadTheme();
2021-09-29 23:57:09 +00:00
}
// 选择主题的对话框
2022-03-23 10:51:38 +00:00
Future<String?> _chooseTheme(BuildContext buildContext) {
return showDialog<String>(
2021-09-29 23:57:09 +00:00
context: buildContext,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
2022-03-23 10:51:38 +00:00
var list = <SimpleDialogOption>[];
list.addAll(_themePackages.map((e) => SimpleDialogOption(
child: Text(e.name()),
onPressed: () {
Navigator.of(context).pop(e.code());
},
)));
return SimpleDialog(
title: const Text("选择主题"),
children: list,
);
});
2021-09-29 23:57:09 +00:00
},
);
2022-03-23 10:51:38 +00:00
}
Future<dynamic> chooseLightTheme(BuildContext buildContext) async {
String? theme = await _chooseTheme(buildContext);
if (theme != null) {
await method.saveProperty(_lightThemePropertyName, theme);
_lightThemeCode = theme;
_reloadTheme();
}
}
Future<dynamic> chooseDarkTheme(BuildContext buildContext) async {
String? theme = await _chooseTheme(buildContext);
2021-09-29 23:57:09 +00:00
if (theme != null) {
2022-03-23 10:51:38 +00:00
await method.saveProperty(_darkThemePropertyName, theme);
_darkThemeCode = theme;
_reloadTheme();
2021-09-29 23:57:09 +00:00
}
}
2022-03-23 10:51:38 +00:00
Future setAndroidNightMode(bool value) async {
await method.saveProperty(_nightModePropertyName, "$value");
androidNightMode = value;
_reloadTheme();
}