From b435a312a6230cefeb78846ce540383da98537b1 Mon Sep 17 00:00:00 2001 From: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> Date: Sat, 10 Jan 2026 16:49:16 +0800 Subject: [PATCH] opt: SlideDialog --- lib/pages/setting/models/style_settings.dart | 122 ++++--------------- lib/pages/setting/widgets/slide_dialog.dart | 105 ++++++++++++---- 2 files changed, 104 insertions(+), 123 deletions(-) diff --git a/lib/pages/setting/models/style_settings.dart b/lib/pages/setting/models/style_settings.dart index 8141b9070..b773e7259 100644 --- a/lib/pages/setting/models/style_settings.dart +++ b/lib/pages/setting/models/style_settings.dart @@ -5,7 +5,6 @@ import 'package:PiliPlus/common/widgets/color_palette.dart'; import 'package:PiliPlus/common/widgets/custom_toast.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; -import 'package:PiliPlus/common/widgets/stateful_builder.dart'; import 'package:PiliPlus/main.dart'; import 'package:PiliPlus/models/common/dynamic/dynamic_badge_mode.dart'; import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart'; @@ -775,109 +774,36 @@ void _showQualityDialog({ }); } -const _minUiScale = 0.5; -const _maxUiScale = 2.0; - -void _showUiScaleDialog( +Future _showUiScaleDialog( BuildContext context, VoidCallback setState, -) { - double uiScale = Pref.uiScale; - final textController = TextEditingController( - text: uiScale.toStringAsFixed(2), - ); +) async { + const minUiScale = 0.5; + const maxUiScale = 2.0; - showDialog( + final result = await showDialog( context: context, builder: (context) { - return AlertDialog( - title: const Text('界面缩放'), - contentPadding: const EdgeInsets.fromLTRB(24, 20, 24, 12), - content: StatefulBuilder( - onDispose: textController.dispose, - builder: (context, setDialogState) { - return Column( - spacing: 20, - mainAxisSize: MainAxisSize.min, - children: [ - Slider( - padding: .zero, - value: uiScale, - min: _minUiScale, - max: _maxUiScale, - secondaryTrackValue: 1.0, - divisions: ((_maxUiScale - _minUiScale) * 20).toInt(), - label: textController.text, - onChanged: (value) => setDialogState(() { - uiScale = value.toPrecision(2); - textController.text = uiScale.toStringAsFixed(2); - }), - ), - TextFormField( - controller: textController, - keyboardType: const TextInputType.numberWithOptions( - decimal: true, - ), - inputFormatters: [ - LengthLimitingTextInputFormatter(4), - FilteringTextInputFormatter.allow(RegExp(r'[\d.]+')), - ], - decoration: const InputDecoration( - labelText: '缩放比例', - hintText: '0.50 - 2.00', - border: OutlineInputBorder(), - ), - onChanged: (value) { - final parsed = double.tryParse(value); - if (parsed != null && - parsed >= _minUiScale && - parsed <= _maxUiScale) { - setDialogState(() { - uiScale = parsed; - }); - } - }, - ), - ], - ); - }, - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context); - Pref.uiScale = 1.0; - GStorage.setting.delete(SettingBoxKey.uiScale).whenComplete(() { - setState(); - Get.appUpdate(); - }); - }, - child: const Text('重置'), - ), - TextButton( - onPressed: () => Navigator.pop(context), - child: Text( - '取消', - style: TextStyle( - color: Theme.of(context).colorScheme.outline, - ), - ), - ), - TextButton( - onPressed: () { - Navigator.pop(context); - Pref.uiScale = uiScale; - GStorage.setting.put(SettingBoxKey.uiScale, uiScale).whenComplete( - () { - setState(); - Get.appUpdate(); - }, - ); - }, - child: const Text('确定'), - ), - ], + return SlideDialog( + value: Pref.uiScale, + title: '界面缩放比例', + min: minUiScale, + max: maxUiScale, + divisions: ((maxUiScale - minUiScale) * 20).toInt(), + precise: 2, + defVal: 1, ); }, ); + + if (result != null) { + if (result.isNaN) { + Pref.uiScale = 1.0; + await GStorage.setting.delete(SettingBoxKey.uiScale); + } else { + Pref.uiScale = result; + await GStorage.setting.put(SettingBoxKey.uiScale, result); + } + Get.appUpdate(); + } } diff --git a/lib/pages/setting/widgets/slide_dialog.dart b/lib/pages/setting/widgets/slide_dialog.dart index 38e04e134..210dcbdcf 100644 --- a/lib/pages/setting/widgets/slide_dialog.dart +++ b/lib/pages/setting/widgets/slide_dialog.dart @@ -1,5 +1,7 @@ import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; class SlideDialog extends StatefulWidget { final double value; @@ -7,8 +9,9 @@ class SlideDialog extends StatefulWidget { final double min; final double max; final int? divisions; - final String suffix; + final String? suffix; final int precise; + final double? defVal; const SlideDialog({ super.key, @@ -17,8 +20,9 @@ class SlideDialog extends StatefulWidget { required this.min, required this.max, this.divisions, - this.suffix = '', + this.suffix, this.precise = 1, + this.defVal, }); @override @@ -27,49 +31,100 @@ class SlideDialog extends StatefulWidget { class _SlideDialogState extends State { late double _tempValue; + late final TextEditingController _controller; @override void initState() { super.initState(); _tempValue = widget.value; + _controller = TextEditingController( + text: _tempValue.toStringAsFixed(widget.precise), + ); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { + final colorScheme = ColorScheme.of(context); return AlertDialog( title: Text(widget.title), - contentPadding: const EdgeInsets.only( - top: 20, - left: 8, - right: 8, - bottom: 8, - ), - content: SizedBox( - height: 40, - child: Slider( - value: _tempValue, - min: widget.min, - max: widget.max, - divisions: widget.divisions, - label: - '${_tempValue.toStringAsFixed(widget.precise)}${widget.suffix}', - onChanged: (double value) { - setState(() { + contentPadding: const .only(top: 24, left: 20, right: 20, bottom: 12), + content: Column( + mainAxisSize: .min, + spacing: 20, + children: [ + Slider( + padding: .zero, + value: _tempValue, + min: widget.min, + max: widget.max, + divisions: widget.divisions, + secondaryTrackValue: widget.defVal, + label: + '${_tempValue.toStringAsFixed(widget.precise)}${widget.suffix ?? ""}', + onChanged: (value) => setState(() { _tempValue = value.toPrecision(widget.precise); - }); - }, - ), + _controller.text = _tempValue.toStringAsFixed(widget.precise); + }), + ), + TextField( + controller: _controller, + maxLines: 1, + keyboardType: const .numberWithOptions(decimal: true), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[\d.]+')), + ], + decoration: InputDecoration( + suffixText: widget.suffix, + labelText: widget.title, + hintText: + '${widget.min.toStringAsFixed(widget.precise)} - ${widget.max.toStringAsFixed(widget.precise)}', + border: const OutlineInputBorder(), + ), + onChanged: (value) { + final parsed = double.tryParse(value); + if (parsed != null && + widget.min <= parsed && + parsed <= widget.max) { + setState(() { + _tempValue = parsed.toPrecision(widget.precise); + }); + } + }, + onSubmitted: (value) { + final parsed = double.tryParse(value); + if (parsed != null) { + setState(() { + _tempValue = parsed + .clamp(widget.min, widget.max) + .toPrecision(widget.precise); + _controller.text = _tempValue.toStringAsFixed(widget.precise); + }); + } + }, + ), + ], ), actions: [ + if (widget.defVal != null) + TextButton( + onPressed: () => Get.back(result: double.nan), + child: Text('重置', style: TextStyle(color: colorScheme.error)), + ), TextButton( - onPressed: Navigator.of(context).pop, + onPressed: Get.back, child: Text( '取消', - style: TextStyle(color: Theme.of(context).colorScheme.outline), + style: TextStyle(color: colorScheme.outline), ), ), TextButton( - onPressed: () => Navigator.pop(context, _tempValue), + onPressed: () => Get.back(result: _tempValue), child: const Text('确定'), ), ],