mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
new: fullscreen rotation angel
This commit is contained in:
@@ -966,6 +966,12 @@ abstract class S {
|
||||
/// **'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.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -465,6 +465,9 @@ class SDe extends S {
|
||||
@override
|
||||
String get result => 'Result';
|
||||
|
||||
@override
|
||||
String get rotateAngel => 'Rotation angle';
|
||||
|
||||
@override
|
||||
String get run => 'Ausführen';
|
||||
|
||||
|
||||
@@ -465,6 +465,9 @@ class SEn extends S {
|
||||
@override
|
||||
String get result => 'Result';
|
||||
|
||||
@override
|
||||
String get rotateAngel => 'Rotation angle';
|
||||
|
||||
@override
|
||||
String get run => 'Run';
|
||||
|
||||
|
||||
@@ -465,6 +465,9 @@ class SZh extends S {
|
||||
@override
|
||||
String get result => '结果';
|
||||
|
||||
@override
|
||||
String get rotateAngel => '旋转角度';
|
||||
|
||||
@override
|
||||
String get run => '运行';
|
||||
|
||||
@@ -1099,6 +1102,9 @@ class SZhTw extends SZh {
|
||||
@override
|
||||
String get result => '結果';
|
||||
|
||||
@override
|
||||
String get rotateAngel => '旋轉角度';
|
||||
|
||||
@override
|
||||
String get run => '運行';
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class SettingStore extends PersistentStore {
|
||||
// Editor theme
|
||||
StoreProperty<String> get editorTheme =>
|
||||
property('editorTheme', defaultValue: defaultEditorTheme);
|
||||
|
||||
|
||||
StoreProperty<String> get editorDarkTheme =>
|
||||
property('editorDarkTheme', defaultValue: defaultEditorDarkTheme);
|
||||
|
||||
@@ -78,6 +78,9 @@ class SettingStore extends PersistentStore {
|
||||
StoreProperty<bool> get fullScreenJitter =>
|
||||
property('fullScreenJitter', defaultValue: true);
|
||||
|
||||
StoreProperty<int> get fullScreenRotateQuarter =>
|
||||
property('fullScreenRotateQuarter', defaultValue: 1);
|
||||
|
||||
StoreProperty<int> get keyboardType =>
|
||||
property('keyboardType', defaultValue: TextInputType.text.index);
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
"restoreSuccess": "Restore success. Restart app to apply.",
|
||||
"restoreSureWithDate": "Are you sure to restore from {date} ?",
|
||||
"result": "Result",
|
||||
"rotateAngel": "Rotation angle",
|
||||
"run": "Run",
|
||||
"save": "Save",
|
||||
"saved": "Saved",
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
"restoreSuccess": "恢复成功,需要重启App来应用更改",
|
||||
"restoreSureWithDate": "确定恢复 {date} 的备份吗?",
|
||||
"result": "结果",
|
||||
"rotateAngel": "旋转角度",
|
||||
"run": "运行",
|
||||
"save": "保存",
|
||||
"saved": "已保存",
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
"restoreSuccess": "恢復成功,需要重啓App來應用更改",
|
||||
"restoreSureWithDate": "確定恢復 {date} 的備份嗎?",
|
||||
"result": "結果",
|
||||
"rotateAngel": "旋轉角度",
|
||||
"run": "運行",
|
||||
"save": "保存",
|
||||
"saved": "已保存",
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
import 'package:toolbox/data/provider/server.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/data/store/setting.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
import '../../core/analysis.dart';
|
||||
@@ -35,14 +36,17 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
late MediaQueryData _media;
|
||||
late ThemeData _theme;
|
||||
late Timer _timer;
|
||||
late int _rotateQuarter;
|
||||
|
||||
final _pageController = PageController(initialPage: 0);
|
||||
final _serverProvider = locator<ServerProvider>();
|
||||
final _setting = locator<SettingStore>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
switchStatusBar(hide: true);
|
||||
_rotateQuarter = _setting.fullScreenRotateQuarter.fetch()!;
|
||||
_timer = Timer.periodic(const Duration(minutes: 1), (_) {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
@@ -68,7 +72,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
|
||||
double get _offset {
|
||||
// based on screen width
|
||||
final x = _media.size.width * 0.03;
|
||||
final x = _screenWidth * 0.03;
|
||||
var r = Random().nextDouble();
|
||||
final n = Random().nextBool() ? -1 : 1;
|
||||
return n * x * r;
|
||||
@@ -79,26 +83,36 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
final offset = Offset(_offset, _offset);
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: RotatedBox(
|
||||
quarterTurns: 3,
|
||||
child: Transform.translate(
|
||||
offset: offset,
|
||||
child: Stack(
|
||||
children: [
|
||||
_buildMain(),
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: _buildSettingBtn(),
|
||||
child: ValueListenableBuilder<int>(
|
||||
valueListenable: _setting.fullScreenRotateQuarter.listenable(),
|
||||
builder: (_, val, __) {
|
||||
_rotateQuarter = val;
|
||||
return RotatedBox(
|
||||
quarterTurns: val,
|
||||
child: Transform.translate(
|
||||
offset: offset,
|
||||
child: Stack(
|
||||
children: [
|
||||
_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() {
|
||||
return IconButton(
|
||||
onPressed: () => AppRoute(
|
||||
@@ -161,7 +175,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: _media.size.width * 0.1),
|
||||
SizedBox(height: _screenWidth * 0.1),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
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(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
@@ -198,7 +212,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
ServerPrivateInfo spi,
|
||||
) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: _media.size.width * 0.05),
|
||||
padding: EdgeInsets.symmetric(vertical: _screenWidth * 0.05),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@@ -245,7 +259,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
|
||||
Widget _buildExplainText(String text) {
|
||||
return SizedBox(
|
||||
width: _media.size.height * 0.2,
|
||||
width: _screenHeight * 0.2,
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
@@ -289,7 +303,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
final statusTextStyle = TextStyle(
|
||||
fontSize: 13, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177));
|
||||
return SizedBox(
|
||||
width: _media.size.height * 0.23,
|
||||
width: _screenHeight * 0.23,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 5),
|
||||
@@ -315,7 +329,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
if (percent <= 0) percent = 0.01;
|
||||
if (percent >= 100) percent = 99.9;
|
||||
return SizedBox(
|
||||
width: _media.size.height * 0.23,
|
||||
width: _screenHeight * 0.23,
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(
|
||||
@@ -324,8 +338,8 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
progressNumber: percent,
|
||||
animationDuration: const Duration(milliseconds: 377),
|
||||
maxNumber: 100,
|
||||
width: _media.size.width * 0.22,
|
||||
height: _media.size.width * 0.22,
|
||||
width: _screenWidth * 0.22,
|
||||
height: _screenWidth * 0.22,
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
|
||||
@@ -45,6 +45,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
final _editorThemeKey = GlobalKey<PopupMenuButtonState<String>>();
|
||||
final _editorDarkThemeKey = GlobalKey<PopupMenuButtonState<String>>();
|
||||
final _keyboardTypeKey = GlobalKey<PopupMenuButtonState<int>>();
|
||||
final _rotateQuarterKey = GlobalKey<PopupMenuButtonState<int>>();
|
||||
|
||||
late final SettingStore _setting;
|
||||
late final ServerProvider _serverProvider;
|
||||
@@ -61,6 +62,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
final _editorTheme = ValueNotifier('');
|
||||
final _editorDarkTheme = ValueNotifier('');
|
||||
final _keyboardType = ValueNotifier(0);
|
||||
final _rotateQuarter = ValueNotifier(0);
|
||||
|
||||
final _pushToken = ValueNotifier<String?>(null);
|
||||
|
||||
@@ -86,6 +88,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
_editorTheme.value = _setting.editorTheme.fetch()!;
|
||||
_editorDarkTheme.value = _setting.editorDarkTheme.fetch()!;
|
||||
_keyboardType.value = _setting.keyboardType.fetch()!;
|
||||
_rotateQuarter.value = _setting.fullScreenRotateQuarter.fetch()!;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -149,6 +152,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
children: [
|
||||
_buildFullScreenSwitch(),
|
||||
_buildFullScreenJitter(),
|
||||
_buildFulScreenRotateQuarter(),
|
||||
].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() {
|
||||
const List<String> names = <String>[
|
||||
'text',
|
||||
|
||||
Reference in New Issue
Block a user