#158 new: follow system color

This commit is contained in:
lollipopkit
2023-09-08 19:47:43 +08:00
parent 7c853e3ea5
commit 84e99048ab
21 changed files with 235 additions and 54 deletions

View File

@@ -530,6 +530,12 @@ abstract class S {
/// **'Finished'** /// **'Finished'**
String get finished; String get finished;
/// No description provided for @followSystem.
///
/// In en, this message translates to:
/// **'Follow system'**
String get followSystem;
/// No description provided for @font. /// No description provided for @font.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -232,6 +232,9 @@ class SDe extends S {
@override @override
String get finished => 'fertiggestellt'; String get finished => 'fertiggestellt';
@override
String get followSystem => 'System verfolgen';
@override @override
String get font => 'Schriftarten'; String get font => 'Schriftarten';

View File

@@ -232,6 +232,9 @@ class SEn extends S {
@override @override
String get finished => 'Finished'; String get finished => 'Finished';
@override
String get followSystem => 'Follow system';
@override @override
String get font => 'Font'; String get font => 'Font';

View File

@@ -232,6 +232,9 @@ class SId extends S {
@override @override
String get finished => 'Selesai'; String get finished => 'Selesai';
@override
String get followSystem => 'Ikuti sistem';
@override @override
String get font => 'Font'; String get font => 'Font';

View File

@@ -232,6 +232,9 @@ class SZh extends S {
@override @override
String get finished => '已完成'; String get finished => '已完成';
@override
String get followSystem => '跟随系统';
@override @override
String get font => '字体'; String get font => '字体';
@@ -964,6 +967,9 @@ class SZhTw extends SZh {
@override @override
String get finished => '已完成'; String get finished => '已完成';
@override
String get followSystem => '跟隨系統';
@override @override
String get font => '字體'; String get font => '字體';

View File

@@ -1,5 +1,7 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/view/page/full_screen.dart'; import 'package:toolbox/view/page/full_screen.dart';
@@ -17,9 +19,9 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DynamicColorBuilder(builder: (light, dark) {
setTransparentNavigationBar(context); setTransparentNavigationBar(context);
primaryColor = Color(_setting.primaryColor.fetch()); _setupPrimaryColor(context, light, dark);
final fullScreen = _setting.fullScreen.fetch();
return ValueListenableBuilder<int>( return ValueListenableBuilder<int>(
valueListenable: _setting.themeMode.listenable(), valueListenable: _setting.themeMode.listenable(),
@@ -36,9 +38,9 @@ class MyApp extends StatelessWidget {
/// After upgrading to flutter 3.13, /// After upgrading to flutter 3.13,
/// the shadow color of the drawer is white (maybe a bug). /// the shadow color of the drawer is white (maybe a bug).
/// Only on [iOS].
/// TODO: remember to remove it after the bug is fixed. /// TODO: remember to remove it after the bug is fixed.
drawerTheme: const DrawerThemeData( drawerTheme: const DrawerThemeData(
backgroundColor: Colors.black,
shadowColor: Colors.black12, shadowColor: Colors.black12,
), ),
); );
@@ -55,10 +57,29 @@ class MyApp extends StatelessWidget {
colorSchemeSeed: primaryColor, colorSchemeSeed: primaryColor,
), ),
darkTheme: isAMOLED ? darkTheme : _getAmoledTheme(darkTheme), darkTheme: isAMOLED ? darkTheme : _getAmoledTheme(darkTheme),
home: fullScreen ? const FullScreenPage() : const HomePage(), home: _setting.fullScreen.fetch()
? const FullScreenPage()
: const HomePage(),
); );
}, },
); );
});
}
void _setupPrimaryColor(
BuildContext context,
ColorScheme? light,
ColorScheme? dark,
) {
if (_setting.useSystemPrimaryColor.fetch()) {
if (context.isDark && light != null) {
primaryColor = light.primary;
} else if (!context.isDark && dark != null) {
primaryColor = dark.primary;
}
} else {
primaryColor = Color(_setting.primaryColor.fetch());
}
} }
} }

View File

@@ -191,6 +191,13 @@ class SettingStore extends PersistentStore {
isDesktop, isDesktop,
); );
/// Whether use system's primary color as the app's primary color
late final useSystemPrimaryColor = StoreProperty(
box,
'useSystemPrimaryColor',
false,
);
// Never show these settings for users // Never show these settings for users
// Guide for these settings: // Guide for these settings:
// - key should start with `_` and be shorter as possible // - key should start with `_` and be shorter as possible

View File

@@ -72,6 +72,7 @@
"fileTooLarge": "Datei '{file}' ist zu groß {size}, max {sizeMax}", "fileTooLarge": "Datei '{file}' ist zu groß {size}, max {sizeMax}",
"files": "Dateien", "files": "Dateien",
"finished": "fertiggestellt", "finished": "fertiggestellt",
"followSystem": "System verfolgen",
"font": "Schriftarten", "font": "Schriftarten",
"fontSize": "Schriftgröße", "fontSize": "Schriftgröße",
"foundNUpdate": "Update {count} gefunden", "foundNUpdate": "Update {count} gefunden",

View File

@@ -72,6 +72,7 @@
"fileTooLarge": "File '{file}' too large {size}, max {sizeMax}", "fileTooLarge": "File '{file}' too large {size}, max {sizeMax}",
"files": "Files", "files": "Files",
"finished": "Finished", "finished": "Finished",
"followSystem": "Follow system",
"font": "Font", "font": "Font",
"fontSize": "Font size", "fontSize": "Font size",
"foundNUpdate": "Found {count} update", "foundNUpdate": "Found {count} update",

View File

@@ -72,6 +72,7 @@
"fileTooLarge": "File '{file}' terlalu besar {size}, max {sizeMax}", "fileTooLarge": "File '{file}' terlalu besar {size}, max {sizeMax}",
"files": "File", "files": "File",
"finished": "Selesai", "finished": "Selesai",
"followSystem": "Ikuti sistem",
"font": "Font", "font": "Font",
"fontSize": "Ukuran huruf", "fontSize": "Ukuran huruf",
"foundNUpdate": "Menemukan {count} pembaruan", "foundNUpdate": "Menemukan {count} pembaruan",

View File

@@ -72,6 +72,7 @@
"fileTooLarge": "文件 '{file}' 过大 '{size}',超过了 {sizeMax}", "fileTooLarge": "文件 '{file}' 过大 '{size}',超过了 {sizeMax}",
"files": "文件", "files": "文件",
"finished": "已完成", "finished": "已完成",
"followSystem": "跟随系统",
"font": "字体", "font": "字体",
"fontSize": "字体大小", "fontSize": "字体大小",
"foundNUpdate": "找到 {count} 个更新", "foundNUpdate": "找到 {count} 个更新",

View File

@@ -72,6 +72,7 @@
"fileTooLarge": "文件 '{file}' 過大 '{size}',超過了 {sizeMax}", "fileTooLarge": "文件 '{file}' 過大 '{size}',超過了 {sizeMax}",
"files": "文件", "files": "文件",
"finished": "已完成", "finished": "已完成",
"followSystem": "跟隨系統",
"font": "字體", "font": "字體",
"fontSize": "字體大小", "fontSize": "字體大小",
"foundNUpdate": "找到 {count} 個更新", "foundNUpdate": "找到 {count} 個更新",

View File

@@ -10,16 +10,14 @@ import 'package:toolbox/core/extension/colorx.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/core/extension/context.dart'; import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/persistant_store.dart';
import 'package:toolbox/core/route.dart';
import 'package:toolbox/data/model/app/net_view.dart';
import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/value_notifier.dart';
import '../../../core/persistant_store.dart';
import '../../../core/route.dart';
import '../../../core/utils/misc.dart'; import '../../../core/utils/misc.dart';
import '../../../core/utils/platform.dart'; import '../../../core/utils/platform.dart';
import '../../../core/update.dart'; import '../../../core/update.dart';
import '../../../core/utils/ui.dart'; import '../../../core/utils/ui.dart';
import '../../../data/model/app/net_view.dart';
import '../../../data/provider/app.dart'; import '../../../data/provider/app.dart';
import '../../../data/provider/server.dart'; import '../../../data/provider/server.dart';
import '../../../data/res/build_data.dart'; import '../../../data/res/build_data.dart';
@@ -29,9 +27,12 @@ import '../../../data/res/ui.dart';
import '../../../data/store/server.dart'; import '../../../data/store/server.dart';
import '../../../data/store/setting.dart'; import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/color_picker.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
import '../../widget/future_widget.dart'; import '../../widget/future_widget.dart';
import '../../widget/input_field.dart';
import '../../widget/round_rect_card.dart'; import '../../widget/round_rect_card.dart';
import '../../widget/value_notifier.dart';
class SettingPage extends StatefulWidget { class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key); const SettingPage({Key? key}) : super(key: key);
@@ -315,14 +316,43 @@ class _SettingPageState extends State<SettingPage> {
await showRoundDialog( await showRoundDialog(
context: context, context: context,
title: Text(_s.primaryColorSeed), title: Text(_s.primaryColorSeed),
child: Input( child: StatefulBuilder(builder: (context, setState) {
autoFocus: true, final children = <Widget>[
/// Plugin [dynamic_color] is not supported on iOS
if (!isIOS) ListTile(
title: Text(_s.followSystem),
trailing: buildSwitch(
context,
_setting.useSystemPrimaryColor,
func: (_) => setState(() {}),
),
)
];
if (!_setting.useSystemPrimaryColor.fetch()) {
children.addAll([
Input(
onSubmitted: _onSaveColor, onSubmitted: _onSaveColor,
controller: ctrl, controller: ctrl,
hint: '#8b2252', hint: '#8b2252',
icon: Icons.colorize, icon: Icons.colorize,
), ),
ColorPicker(
color: primaryColor,
onColorChanged: (c) => ctrl.text = c.toHex,
)
]);
}
return Column(
mainAxisSize: MainAxisSize.min,
children: children,
); );
}),
actions: [
TextButton(
onPressed: () => _onSaveColor(ctrl.text),
child: Text(_s.ok),
),
]);
}, },
); );
} }

View File

@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
enum _ColorPropType {
r,
g,
b,
}
class ColorPicker extends StatefulWidget {
final Color color;
final ValueChanged<Color> onColorChanged;
const ColorPicker({
super.key,
required this.color,
required this.onColorChanged,
});
@override
_ColorPickerState createState() => _ColorPickerState();
}
class _ColorPickerState extends State<ColorPicker> {
late int _r = widget.color.red;
late int _g = widget.color.green;
late int _b = widget.color.blue;
@override
Widget build(BuildContext context) {
return Column(
children: [
_buildProgress(_ColorPropType.r, 'R', _r.toDouble()),
_buildProgress(_ColorPropType.g, 'G', _g.toDouble()),
_buildProgress(_ColorPropType.b, 'B', _b.toDouble()),
],
);
}
Widget _buildProgress(_ColorPropType type, String title, double value) {
return Row(
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Expanded(
child: Slider(
value: value,
onChanged: (v) {
setState(() {
switch (type) {
case _ColorPropType.r:
_r = v.toInt();
break;
case _ColorPropType.g:
_g = v.toInt();
break;
case _ColorPropType.b:
_b = v.toInt();
break;
}
});
widget.onColorChanged(Color.fromARGB(255, _r, _g, _b));
},
min: 0,
max: 255,
divisions: 255,
label: value.toInt().toString(),
),
),
],
);
}
}

View File

@@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
url_launcher_linux url_launcher_linux
) )

View File

@@ -5,6 +5,7 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import dynamic_color
import macos_window_utils import macos_window_utils
import path_provider_foundation import path_provider_foundation
import share_plus import share_plus
@@ -12,6 +13,7 @@ import shared_preferences_foundation
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin")) MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))

View File

@@ -250,6 +250,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.3.2" version: "5.3.2"
dynamic_color:
dependency: "direct main"
description:
name: dynamic_color
sha256: de4798a7069121aee12d5895315680258415de9b00e717723a1bd73d58f0126d
url: "https://pub.dev"
source: hosted
version: "1.6.6"
easy_isolate: easy_isolate:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -47,6 +47,7 @@ dependencies:
shared_preferences: ^2.1.1 shared_preferences: ^2.1.1
crypto: ^3.0.3 crypto: ^3.0.3
macos_window_utils: ^1.2.0 macos_window_utils: ^1.2.0
dynamic_color: ^1.6.6
dev_dependencies: dev_dependencies:
flutter_native_splash: ^2.1.6 flutter_native_splash: ^2.1.6

View File

@@ -6,10 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
SharePlusWindowsPluginCApiRegisterWithRegistrar( SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
share_plus share_plus
url_launcher_windows url_launcher_windows
) )