new: fullscreen rotation angel

This commit is contained in:
lollipopkit
2023-06-27 13:31:35 +08:00
parent 76e8a1efca
commit 92e2e2a75f
10 changed files with 100 additions and 25 deletions

View File

@@ -966,6 +966,12 @@ abstract class S {
/// **'Result'** /// **'Result'**
String get result; String get result;
/// No description provided for @rotateAngel.
///
/// In en, this message translates to:
/// **'Rotation angle'**
String get rotateAngel;
/// No description provided for @run. /// No description provided for @run.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -465,6 +465,9 @@ class SDe extends S {
@override @override
String get result => 'Result'; String get result => 'Result';
@override
String get rotateAngel => 'Rotation angle';
@override @override
String get run => 'Ausführen'; String get run => 'Ausführen';

View File

@@ -465,6 +465,9 @@ class SEn extends S {
@override @override
String get result => 'Result'; String get result => 'Result';
@override
String get rotateAngel => 'Rotation angle';
@override @override
String get run => 'Run'; String get run => 'Run';

View File

@@ -465,6 +465,9 @@ class SZh extends S {
@override @override
String get result => '结果'; String get result => '结果';
@override
String get rotateAngel => '旋转角度';
@override @override
String get run => '运行'; String get run => '运行';
@@ -1099,6 +1102,9 @@ class SZhTw extends SZh {
@override @override
String get result => '結果'; String get result => '結果';
@override
String get rotateAngel => '旋轉角度';
@override @override
String get run => '運行'; String get run => '運行';

View File

@@ -68,7 +68,7 @@ class SettingStore extends PersistentStore {
// Editor theme // Editor theme
StoreProperty<String> get editorTheme => StoreProperty<String> get editorTheme =>
property('editorTheme', defaultValue: defaultEditorTheme); property('editorTheme', defaultValue: defaultEditorTheme);
StoreProperty<String> get editorDarkTheme => StoreProperty<String> get editorDarkTheme =>
property('editorDarkTheme', defaultValue: defaultEditorDarkTheme); property('editorDarkTheme', defaultValue: defaultEditorDarkTheme);
@@ -78,6 +78,9 @@ class SettingStore extends PersistentStore {
StoreProperty<bool> get fullScreenJitter => StoreProperty<bool> get fullScreenJitter =>
property('fullScreenJitter', defaultValue: true); property('fullScreenJitter', defaultValue: true);
StoreProperty<int> get fullScreenRotateQuarter =>
property('fullScreenRotateQuarter', defaultValue: 1);
StoreProperty<int> get keyboardType => StoreProperty<int> get keyboardType =>
property('keyboardType', defaultValue: TextInputType.text.index); property('keyboardType', defaultValue: TextInputType.text.index);

View File

@@ -145,6 +145,7 @@
"restoreSuccess": "Restore success. Restart app to apply.", "restoreSuccess": "Restore success. Restart app to apply.",
"restoreSureWithDate": "Are you sure to restore from {date} ?", "restoreSureWithDate": "Are you sure to restore from {date} ?",
"result": "Result", "result": "Result",
"rotateAngel": "Rotation angle",
"run": "Run", "run": "Run",
"save": "Save", "save": "Save",
"saved": "Saved", "saved": "Saved",

View File

@@ -145,6 +145,7 @@
"restoreSuccess": "恢复成功需要重启App来应用更改", "restoreSuccess": "恢复成功需要重启App来应用更改",
"restoreSureWithDate": "确定恢复 {date} 的备份吗?", "restoreSureWithDate": "确定恢复 {date} 的备份吗?",
"result": "结果", "result": "结果",
"rotateAngel": "旋转角度",
"run": "运行", "run": "运行",
"save": "保存", "save": "保存",
"saved": "已保存", "saved": "已保存",

View File

@@ -142,6 +142,7 @@
"restoreSuccess": "恢復成功需要重啓App來應用更改", "restoreSuccess": "恢復成功需要重啓App來應用更改",
"restoreSureWithDate": "確定恢復 {date} 的備份嗎?", "restoreSureWithDate": "確定恢復 {date} 的備份嗎?",
"result": "結果", "result": "結果",
"rotateAngel": "旋轉角度",
"run": "運行", "run": "運行",
"save": "保存", "save": "保存",
"saved": "已保存", "saved": "已保存",

View File

@@ -10,6 +10,7 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/route.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
import '../../core/analysis.dart'; import '../../core/analysis.dart';
@@ -35,14 +36,17 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
late MediaQueryData _media; late MediaQueryData _media;
late ThemeData _theme; late ThemeData _theme;
late Timer _timer; late Timer _timer;
late int _rotateQuarter;
final _pageController = PageController(initialPage: 0); final _pageController = PageController(initialPage: 0);
final _serverProvider = locator<ServerProvider>(); final _serverProvider = locator<ServerProvider>();
final _setting = locator<SettingStore>();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
switchStatusBar(hide: true); switchStatusBar(hide: true);
_rotateQuarter = _setting.fullScreenRotateQuarter.fetch()!;
_timer = Timer.periodic(const Duration(minutes: 1), (_) { _timer = Timer.periodic(const Duration(minutes: 1), (_) {
if (mounted) { if (mounted) {
setState(() {}); setState(() {});
@@ -68,7 +72,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
double get _offset { double get _offset {
// based on screen width // based on screen width
final x = _media.size.width * 0.03; final x = _screenWidth * 0.03;
var r = Random().nextDouble(); var r = Random().nextDouble();
final n = Random().nextBool() ? -1 : 1; final n = Random().nextBool() ? -1 : 1;
return n * x * r; return n * x * r;
@@ -79,26 +83,36 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
final offset = Offset(_offset, _offset); final offset = Offset(_offset, _offset);
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: RotatedBox( child: ValueListenableBuilder<int>(
quarterTurns: 3, valueListenable: _setting.fullScreenRotateQuarter.listenable(),
child: Transform.translate( builder: (_, val, __) {
offset: offset, _rotateQuarter = val;
child: Stack( return RotatedBox(
children: [ quarterTurns: val,
_buildMain(), child: Transform.translate(
Positioned( offset: offset,
top: 0, child: Stack(
left: 0, children: [
child: _buildSettingBtn(), _buildMain(),
Positioned(
top: 0,
left: 0,
child: _buildSettingBtn(),
),
],
),
), ),
], );
), }),
),
),
), ),
); );
} }
double get _screenWidth =>
_rotateQuarter % 2 == 0 ? _media.size.width : _media.size.height;
double get _screenHeight =>
_rotateQuarter % 2 == 0 ? _media.size.height : _media.size.width;
Widget _buildSettingBtn() { Widget _buildSettingBtn() {
return IconButton( return IconButton(
onPressed: () => AppRoute( onPressed: () => AppRoute(
@@ -161,7 +175,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SizedBox(height: _media.size.width * 0.1), SizedBox(height: _screenWidth * 0.1),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@@ -175,7 +189,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
) )
], ],
), ),
SizedBox(height: _media.size.width * 0.1), SizedBox(height: _screenWidth * 0.1),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@@ -198,7 +212,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
ServerPrivateInfo spi, ServerPrivateInfo spi,
) { ) {
return Padding( return Padding(
padding: EdgeInsets.symmetric(vertical: _media.size.width * 0.05), padding: EdgeInsets.symmetric(vertical: _screenWidth * 0.05),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@@ -245,7 +259,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
Widget _buildExplainText(String text) { Widget _buildExplainText(String text) {
return SizedBox( return SizedBox(
width: _media.size.height * 0.2, width: _screenHeight * 0.2,
child: Text( child: Text(
text, text,
style: const TextStyle(fontSize: 13), style: const TextStyle(fontSize: 13),
@@ -289,7 +303,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
final statusTextStyle = TextStyle( final statusTextStyle = TextStyle(
fontSize: 13, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177)); fontSize: 13, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177));
return SizedBox( return SizedBox(
width: _media.size.height * 0.23, width: _screenHeight * 0.23,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 5), const SizedBox(height: 5),
@@ -315,7 +329,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
if (percent <= 0) percent = 0.01; if (percent <= 0) percent = 0.01;
if (percent >= 100) percent = 99.9; if (percent >= 100) percent = 99.9;
return SizedBox( return SizedBox(
width: _media.size.height * 0.23, width: _screenHeight * 0.23,
child: Stack( child: Stack(
children: [ children: [
Center( Center(
@@ -324,8 +338,8 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
progressNumber: percent, progressNumber: percent,
animationDuration: const Duration(milliseconds: 377), animationDuration: const Duration(milliseconds: 377),
maxNumber: 100, maxNumber: 100,
width: _media.size.width * 0.22, width: _screenWidth * 0.22,
height: _media.size.width * 0.22, height: _screenWidth * 0.22,
), ),
), ),
Positioned.fill( Positioned.fill(

View File

@@ -45,6 +45,7 @@ class _SettingPageState extends State<SettingPage> {
final _editorThemeKey = GlobalKey<PopupMenuButtonState<String>>(); final _editorThemeKey = GlobalKey<PopupMenuButtonState<String>>();
final _editorDarkThemeKey = GlobalKey<PopupMenuButtonState<String>>(); final _editorDarkThemeKey = GlobalKey<PopupMenuButtonState<String>>();
final _keyboardTypeKey = GlobalKey<PopupMenuButtonState<int>>(); final _keyboardTypeKey = GlobalKey<PopupMenuButtonState<int>>();
final _rotateQuarterKey = GlobalKey<PopupMenuButtonState<int>>();
late final SettingStore _setting; late final SettingStore _setting;
late final ServerProvider _serverProvider; late final ServerProvider _serverProvider;
@@ -61,6 +62,7 @@ class _SettingPageState extends State<SettingPage> {
final _editorTheme = ValueNotifier(''); final _editorTheme = ValueNotifier('');
final _editorDarkTheme = ValueNotifier(''); final _editorDarkTheme = ValueNotifier('');
final _keyboardType = ValueNotifier(0); final _keyboardType = ValueNotifier(0);
final _rotateQuarter = ValueNotifier(0);
final _pushToken = ValueNotifier<String?>(null); final _pushToken = ValueNotifier<String?>(null);
@@ -86,6 +88,7 @@ class _SettingPageState extends State<SettingPage> {
_editorTheme.value = _setting.editorTheme.fetch()!; _editorTheme.value = _setting.editorTheme.fetch()!;
_editorDarkTheme.value = _setting.editorDarkTheme.fetch()!; _editorDarkTheme.value = _setting.editorDarkTheme.fetch()!;
_keyboardType.value = _setting.keyboardType.fetch()!; _keyboardType.value = _setting.keyboardType.fetch()!;
_rotateQuarter.value = _setting.fullScreenRotateQuarter.fetch()!;
} }
@override @override
@@ -149,6 +152,7 @@ class _SettingPageState extends State<SettingPage> {
children: [ children: [
_buildFullScreenSwitch(), _buildFullScreenSwitch(),
_buildFullScreenJitter(), _buildFullScreenJitter(),
_buildFulScreenRotateQuarter(),
].map((e) => RoundRectCard(e)).toList(), ].map((e) => RoundRectCard(e)).toList(),
); );
} }
@@ -730,6 +734,39 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
Widget _buildFulScreenRotateQuarter() {
final degrees = List.generate(4, (idx) => '${idx * 90}°').toList();
final items = List.generate(4, (idx) {
return PopupMenuItem<int>(
value: idx,
child: Text(degrees[idx]),
);
}).toList();
return ListTile(
title: Text(_s.rotateAngel),
onTap: () {
_rotateQuarterKey.currentState?.showButtonMenu();
},
trailing: ValueBuilder(
listenable: _rotateQuarter,
build: () => PopupMenuButton(
key: _rotateQuarterKey,
itemBuilder: (BuildContext context) => items,
initialValue: _rotateQuarter.value,
onSelected: (int idx) {
_rotateQuarter.value = idx;
_setting.fullScreenRotateQuarter.put(idx);
},
child: Text(
degrees[_rotateQuarter.value],
style: textSize15,
),
),
),
);
}
Widget _buildKeyboardType() { Widget _buildKeyboardType() {
const List<String> names = <String>[ const List<String> names = <String>[
'text', 'text',