diff --git a/ci/version.info.txt b/ci/version.info.txt index b1d8d11..32c8ca7 100644 --- a/ci/version.info.txt +++ b/ci/version.info.txt @@ -1,2 +1,3 @@ v1.7.3 - [x] ✨ 可以隐藏发电图标 +- [x] ✨ 可以给阅读器加灰度滤镜(设置项)(墨水屏下或许有用) diff --git a/lib/basic/config/ImageFilter.dart b/lib/basic/config/ImageFilter.dart new file mode 100644 index 0000000..506fbe2 --- /dev/null +++ b/lib/basic/config/ImageFilter.dart @@ -0,0 +1,108 @@ +import 'package:flutter/material.dart'; + +import '../Common.dart'; +import '../Method.dart'; + +const _propertyName = "imageFilter"; +late ImageFilter imageFilter; + +Widget processImageFilter(Widget child) => imageFilter.process(child); + +Future initImageFilter() async { + imageFilter = _imageFilterFromString(await method.loadProperty( + _propertyName, + _filters[0].name, + )); +} + +ImageFilter _imageFilterFromString(String string) { + for (var value in _filters) { + if (string == value.name) { + return value; + } + } + return _filters[0]; +} + +class ImageFilter { + final String name; + final Widget Function(Widget widget) process; + + ImageFilter(this.name, this.process); +} + +final List _filters = [ + ImageFilter( + "正常", + (child) { + return child; + }, + ), + ImageFilter( + "灰度", + (child) { + return ColorFiltered( + colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.color), + child: child, + ); + }, + ), + ImageFilter( + "棕褐色", + (child) { + return ColorFiltered( + colorFilter: const ColorFilter.matrix([ 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0, ]), + child: child, + ); + }, + ), + ImageFilter( + "srgbToLinearGamma", + (child) { + return ColorFiltered( + colorFilter: const ColorFilter.srgbToLinearGamma(), + child: child, + ); + }, + ), + ImageFilter( + "linearToSrgbGamma", + (child) { + return ColorFiltered( + colorFilter: const ColorFilter.linearToSrgbGamma(), + child: child, + ); + }, + ), +]; + +Future chooseImageFilter(BuildContext context) async { + Map map = {}; + for (var element in _filters) { + map[element.name] = element; + } + ImageFilter? result = await chooseMapDialog( + context, + map, + "选择全屏UI", + ); + if (result != null) { + await method.saveProperty(_propertyName, result.name); + imageFilter = result; + } +} + +Widget imageFilterSetting() { + return StatefulBuilder( + builder: (BuildContext context, void Function(void Function()) setState) { + return ListTile( + title: const Text("阅读器滤镜"), + subtitle: Text(imageFilter.name), + onTap: () async { + await chooseImageFilter(context); + setState(() {}); + }, + ); + }, + ); +} diff --git a/lib/screens/InitScreen.dart b/lib/screens/InitScreen.dart index c450ea3..fba46a8 100644 --- a/lib/screens/InitScreen.dart +++ b/lib/screens/InitScreen.dart @@ -16,6 +16,7 @@ import 'package:pikapika/basic/config/DownloadThreadCount.dart'; import 'package:pikapika/basic/config/FullScreenAction.dart'; import 'package:pikapika/basic/config/FullScreenUI.dart'; import 'package:pikapika/basic/config/ImageAddress.dart'; +import 'package:pikapika/basic/config/ImageFilter.dart'; import 'package:pikapika/basic/config/KeyboardController.dart'; import 'package:pikapika/basic/config/NoAnimation.dart'; import 'package:pikapika/basic/config/PagerAction.dart'; @@ -115,6 +116,7 @@ class _InitScreenState extends State { await initDownloadCachePath(); await initUseApiLoadImage(); await initWebDav(); + await initImageFilter(); String? initUrl; if (Platform.isAndroid || Platform.isIOS) { diff --git a/lib/screens/SettingsScreen.dart b/lib/screens/SettingsScreen.dart index 0b8424b..44df987 100644 --- a/lib/screens/SettingsScreen.dart +++ b/lib/screens/SettingsScreen.dart @@ -35,6 +35,7 @@ import '../basic/config/Authentication.dart'; import '../basic/config/CategoriesColumnCount.dart'; import '../basic/config/DownloadCachePath.dart'; import '../basic/config/HiddenFdIcon.dart'; +import '../basic/config/ImageFilter.dart'; import '../basic/config/UsingRightClickPop.dart'; import '../basic/config/WebDav.dart'; import '../basic/config/WillPopNotice.dart'; @@ -159,6 +160,8 @@ class _SettingsScreenState extends State { volumeControllerSetting(), keyboardControllerSetting(), const Divider(), + imageFilterSetting(), + const Divider(), const Padding(padding: EdgeInsets.only(top: 15)), ]), _IconAndWidgets(Icons.download, [ diff --git a/lib/screens/components/ImageReader.dart b/lib/screens/components/ImageReader.dart index 06f56bf..96a78b2 100644 --- a/lib/screens/components/ImageReader.dart +++ b/lib/screens/components/ImageReader.dart @@ -14,6 +14,7 @@ import 'package:pikapika/basic/Method.dart'; import 'package:pikapika/basic/config/Address.dart'; import 'package:pikapika/basic/config/FullScreenAction.dart'; import 'package:pikapika/basic/config/ImageAddress.dart'; +import 'package:pikapika/basic/config/ImageFilter.dart'; import 'package:pikapika/basic/config/KeyboardController.dart'; import 'package:pikapika/basic/config/NoAnimation.dart'; import 'package:pikapika/basic/config/Quality.dart'; @@ -228,6 +229,8 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> { // 阅读器 Widget _buildViewer(); + Widget _buildViewerProcess() => processImageFilter(_buildViewer()); + // 键盘, 音量键 等事件 void _needJumpTo(int index, bool animation); @@ -308,35 +311,35 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> { case FullScreenAction.CONTROLLER: return Stack( children: [ - _buildViewer(), + _buildViewerProcess(), _buildBar(_buildFullScreenControllerStackItem()), ], ); case FullScreenAction.TOUCH_ONCE: return Stack( children: [ - _buildTouchOnceControllerAction(_buildViewer()), + _buildTouchOnceControllerAction(_buildViewerProcess()), _buildBar(Container()), ], ); case FullScreenAction.TOUCH_DOUBLE: return Stack( children: [ - _buildTouchDoubleControllerAction(_buildViewer()), + _buildTouchDoubleControllerAction(_buildViewerProcess()), _buildBar(Container()), ], ); case FullScreenAction.TOUCH_DOUBLE_ONCE_NEXT: return Stack( children: [ - _buildTouchDoubleOnceNextControllerAction(_buildViewer()), + _buildTouchDoubleOnceNextControllerAction(_buildViewerProcess()), _buildBar(Container()), ], ); case FullScreenAction.THREE_AREA: return Stack( children: [ - _buildViewer(), + _buildViewerProcess(), _buildBar(_buildThreeAreaControllerAction()), ], ); @@ -934,13 +937,15 @@ class _SettingPanelState extends State<_SettingPanel> { widget.onReloadEp(); }, ), - // _bottomIcon( - // icon: Icons.file_download, - // title: "下载本作", - // onPressed: widget.onDownload, - // ), ], ), + // Row(children: [ + // _bottomIcon( + // icon: Icons.file_download, + // title: "下载本作", + // onPressed: widget.onDownload, + // ), + // ]), ], ); } diff --git a/pubspec.lock b/pubspec.lock index 318e637..5ec537c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -133,10 +133,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "0d923fb610d0abf67f2149c3a50ef85f78bebecfc4d645719ca70bcf4abc788f" + sha256: dd328189f2f4ccea042bb5b382d5e981691cc74b5a3429b9317bff2b19704489 url: "https://pub.dev" source: hosted - version: "5.2.7" + version: "5.2.8" filesystem_picker: dependency: "direct main" description: @@ -249,10 +249,10 @@ packages: dependency: "direct main" description: name: image_picker - sha256: cb25f04595a88450970dbe727243ba8cd21b6f7e0d7d1fc5b789fc6f52e95494 + sha256: "8b0efbf350ba4f2be1531d629396a994983d0c02f4a82a128aed84d954b90cfa" url: "https://pub.dev" source: hosted - version: "0.8.7+1" + version: "0.8.7+2" image_picker_android: dependency: transitive description: @@ -590,10 +590,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "0ef2b4f97942a16523e51256b799e9aa1843da6c60c55eefbfa9dbc2dcb8331a" + sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "3.0.5" url_launcher_platform_interface: dependency: transitive description: