new: fullscreen rotation angel
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
|
|||||||
@@ -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 => '運行';
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -145,6 +145,7 @@
|
|||||||
"restoreSuccess": "恢复成功,需要重启App来应用更改",
|
"restoreSuccess": "恢复成功,需要重启App来应用更改",
|
||||||
"restoreSureWithDate": "确定恢复 {date} 的备份吗?",
|
"restoreSureWithDate": "确定恢复 {date} 的备份吗?",
|
||||||
"result": "结果",
|
"result": "结果",
|
||||||
|
"rotateAngel": "旋转角度",
|
||||||
"run": "运行",
|
"run": "运行",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"saved": "已保存",
|
"saved": "已保存",
|
||||||
|
|||||||
@@ -142,6 +142,7 @@
|
|||||||
"restoreSuccess": "恢復成功,需要重啓App來應用更改",
|
"restoreSuccess": "恢復成功,需要重啓App來應用更改",
|
||||||
"restoreSureWithDate": "確定恢復 {date} 的備份嗎?",
|
"restoreSureWithDate": "確定恢復 {date} 的備份嗎?",
|
||||||
"result": "結果",
|
"result": "結果",
|
||||||
|
"rotateAngel": "旋轉角度",
|
||||||
"run": "運行",
|
"run": "運行",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"saved": "已保存",
|
"saved": "已保存",
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user