reader slider position config

This commit is contained in:
niuhuan 2021-12-09 08:08:01 +08:00
parent 5b4771d988
commit 91560c4538
6 changed files with 326 additions and 135 deletions

View File

@ -21,9 +21,7 @@ Future<void> initAddress() async {
_currentAddress = await method.getSwitchAddress(); _currentAddress = await method.getSwitchAddress();
} }
String currentAddressName() { String currentAddressName() => _addresses[_currentAddress] ?? "";
return _addresses[_currentAddress] ?? "";
}
Future<void> chooseAddress(BuildContext context) async { Future<void> chooseAddress(BuildContext context) async {
String? choose = await showDialog<String>( String? choose = await showDialog<String>(

View File

@ -21,9 +21,7 @@ int currentImageAddress() {
return int.parse(_currentImageAddress); return int.parse(_currentImageAddress);
} }
String currentImageAddressName() { String currentImageAddressName() => _imageAddresses[_currentImageAddress] ?? "";
return _imageAddresses[_currentImageAddress] ?? "";
}
Future<void> chooseImageAddress(BuildContext context) async { Future<void> chooseImageAddress(BuildContext context) async {
String? choose = await showDialog<String>( String? choose = await showDialog<String>(

View File

@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:pikapika/basic/Method.dart';
import '../Common.dart';
enum ReaderSliderPosition { BOTTOM, RIGHT, LEFT }
const _positionNames = {
ReaderSliderPosition.BOTTOM: '下方',
ReaderSliderPosition.RIGHT: '右侧',
ReaderSliderPosition.LEFT: '左侧',
};
const _propertyName = "readerSliderPosition";
late ReaderSliderPosition _readerSliderPosition;
Future initReaderSliderPosition() async {
_readerSliderPosition = _readerSliderPositionFromString(
await method.loadProperty(_propertyName, ""),
);
}
ReaderSliderPosition _readerSliderPositionFromString(String str) {
for (var value in ReaderSliderPosition.values) {
if (str == value.toString()) return value;
}
return ReaderSliderPosition.BOTTOM;
}
ReaderSliderPosition currentReaderSliderPosition() => _readerSliderPosition;
String currentReaderSliderPositionName() =>
_positionNames[_readerSliderPosition] ?? "";
Future<void> chooseReaderSliderPosition(BuildContext context) async {
Map<String, ReaderSliderPosition> map = {};
_positionNames.forEach((key, value) {
map[value] = key;
});
ReaderSliderPosition? result =
await chooseMapDialog<ReaderSliderPosition>(context, map, "选择操控方式");
if (result != null) {
await method.saveProperty(_propertyName, result.toString());
_readerSliderPosition = result;
}
}
Widget readerSliderPositionSetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: Text("滚动条的位置"),
subtitle: Text(currentReaderSliderPositionName()),
onTap: () async {
await chooseReaderSliderPosition(context);
setState(() {});
},
);
},
);
}

View File

@ -19,6 +19,7 @@ import 'package:pikapika/basic/config/Platform.dart';
import 'package:pikapika/basic/config/Proxy.dart'; import 'package:pikapika/basic/config/Proxy.dart';
import 'package:pikapika/basic/config/Quality.dart'; import 'package:pikapika/basic/config/Quality.dart';
import 'package:pikapika/basic/config/ReaderDirection.dart'; import 'package:pikapika/basic/config/ReaderDirection.dart';
import 'package:pikapika/basic/config/ReaderSliderPosition.dart';
import 'package:pikapika/basic/config/ReaderType.dart'; import 'package:pikapika/basic/config/ReaderType.dart';
import 'package:pikapika/basic/config/ShadowCategories.dart'; import 'package:pikapika/basic/config/ShadowCategories.dart';
import 'package:pikapika/basic/config/Themes.dart'; import 'package:pikapika/basic/config/Themes.dart';
@ -58,6 +59,7 @@ class _InitScreenState extends State<InitScreen> {
await initListLayout(); await initListLayout();
await initReaderType(); await initReaderType();
await initReaderDirection(); await initReaderDirection();
await initReaderSliderPosition();
await initAutoFullScreen(); await initAutoFullScreen();
await initFullScreenAction(); await initFullScreenAction();
await initPagerAction(); await initPagerAction();

View File

@ -17,6 +17,7 @@ import 'package:pikapika/basic/config/KeyboardController.dart';
import 'package:pikapika/basic/config/NoAnimation.dart'; import 'package:pikapika/basic/config/NoAnimation.dart';
import 'package:pikapika/basic/config/PagerAction.dart'; import 'package:pikapika/basic/config/PagerAction.dart';
import 'package:pikapika/basic/config/ReaderDirection.dart'; import 'package:pikapika/basic/config/ReaderDirection.dart';
import 'package:pikapika/basic/config/ReaderSliderPosition.dart';
import 'package:pikapika/basic/config/ReaderType.dart'; import 'package:pikapika/basic/config/ReaderType.dart';
import 'package:pikapika/basic/config/Quality.dart'; import 'package:pikapika/basic/config/Quality.dart';
import 'package:pikapika/basic/config/ShadowCategories.dart'; import 'package:pikapika/basic/config/ShadowCategories.dart';
@ -43,6 +44,7 @@ class SettingsScreen extends StatelessWidget {
convertToPNGSetting(), convertToPNGSetting(),
readerTypeSetting(), readerTypeSetting(),
readerDirectionSetting(), readerDirectionSetting(),
readerSliderPositionSetting(),
autoFullScreenSetting(), autoFullScreenSetting(),
fullScreenActionSetting(), fullScreenActionSetting(),
volumeControllerSetting(), volumeControllerSetting(),

View File

@ -19,6 +19,7 @@ import 'package:pikapika/basic/config/KeyboardController.dart';
import 'package:pikapika/basic/config/NoAnimation.dart'; import 'package:pikapika/basic/config/NoAnimation.dart';
import 'package:pikapika/basic/config/Quality.dart'; import 'package:pikapika/basic/config/Quality.dart';
import 'package:pikapika/basic/config/ReaderDirection.dart'; import 'package:pikapika/basic/config/ReaderDirection.dart';
import 'package:pikapika/basic/config/ReaderSliderPosition.dart';
import 'package:pikapika/basic/config/ReaderType.dart'; import 'package:pikapika/basic/config/ReaderType.dart';
import 'package:pikapika/basic/config/VolumeController.dart'; import 'package:pikapika/basic/config/VolumeController.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
@ -152,20 +153,20 @@ class _ImageReaderState extends State<ImageReader> {
// //
final ReaderType _pagerType = currentReaderType(); final ReaderType _pagerType = currentReaderType();
//
final _currentQuality = currentQualityCode();
// //
late FullScreenAction _fullScreenAction = currentFullScreenAction(); late FullScreenAction _fullScreenAction = currentFullScreenAction();
late ReaderSliderPosition _readerSliderPosition =
currentReaderSliderPosition();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _ImageReaderContent( return _ImageReaderContent(
widget.struct, widget.struct,
_pagerDirection, _pagerDirection,
_pagerType, _pagerType,
_currentQuality,
_fullScreenAction, _fullScreenAction,
_readerSliderPosition,
); );
} }
} }
@ -179,18 +180,18 @@ class _ImageReaderContent extends StatefulWidget {
// //
final ReaderType pagerType; final ReaderType pagerType;
//
final String currentQuality;
final FullScreenAction fullScreenAction; final FullScreenAction fullScreenAction;
final ReaderSliderPosition readerSliderPosition;
final ImageReaderStruct struct; final ImageReaderStruct struct;
const _ImageReaderContent( const _ImageReaderContent(
this.struct, this.struct,
this.pagerDirection, this.pagerDirection,
this.pagerType, this.pagerType,
this.currentQuality,
this.fullScreenAction, this.fullScreenAction,
this.readerSliderPosition,
); );
@override @override
@ -298,24 +299,11 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
} }
Widget _buildBar() { Widget _buildBar() {
switch (widget.readerSliderPosition) {
case ReaderSliderPosition.BOTTOM:
return Column( return Column(
children: [ children: [
widget.struct.fullScreen _buildAppBar(),
? Container()
: AppBar(
title: Text(
"${widget.struct.epNameMap[widget.struct.epOrder] ?? ""} - ${widget.struct.comicTitle}"),
actions: [
IconButton(
onPressed: _onChooseEp,
icon: Icon(Icons.menu_open),
),
IconButton(
onPressed: _onMoreSetting,
icon: Icon(Icons.more_horiz),
),
],
),
Expanded(child: _buildController()), Expanded(child: _buildController()),
widget.struct.fullScreen widget.struct.fullScreen
? Container() ? Container()
@ -336,8 +324,9 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
), ),
Container(width: 10), Container(width: 10),
Expanded( Expanded(
child: widget.pagerType != ReaderType.WEB_TOON_FREE_ZOOM child:
? _buildSlider() widget.pagerType != ReaderType.WEB_TOON_FREE_ZOOM
? _buildSliderBottom()
: Container(), : Container(),
), ),
Container(width: 10), Container(width: 10),
@ -352,16 +341,119 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
), ),
], ],
); );
case ReaderSliderPosition.RIGHT:
return Column(
children: [
_buildAppBar(),
Expanded(
child: Stack(
children: [
_buildController(),
_buildSliderRight(),
],
),
),
],
);
case ReaderSliderPosition.LEFT:
return Column(
children: [
_buildAppBar(),
Expanded(
child: Stack(
children: [
_buildController(),
_buildSliderLeft(),
],
),
),
],
);
}
return Container();
} }
Widget _buildSlider() { Widget _buildAppBar() => widget.struct.fullScreen
? Container()
: AppBar(
title: Text(
"${widget.struct.epNameMap[widget.struct.epOrder] ?? ""} - ${widget.struct.comicTitle}"),
actions: [
IconButton(
onPressed: _onChooseEp,
icon: Icon(Icons.menu_open),
),
IconButton(
onPressed: _onMoreSetting,
icon: Icon(Icons.more_horiz),
),
],
);
Widget _buildSliderBottom() {
return Column( return Column(
children: [ children: [
Expanded(child: Container()), Expanded(child: Container()),
Container( Container(
height: 25, height: 25,
child: FlutterSlider( child: _buildSliderWidget(Axis.horizontal),
axis: Axis.horizontal, ),
Expanded(child: Container()),
],
);
}
Widget _buildSliderLeft() => widget.struct.fullScreen
? Container()
: Align(
alignment: Alignment.centerLeft,
child: Material(
color: Color(0x0),
child: Container(
width: 35,
height: 300,
decoration: BoxDecoration(
color: Color(0x66000000),
borderRadius: BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
padding: EdgeInsets.only(top: 10, bottom: 10, left: 6, right: 5),
child: Center(
child: _buildSliderWidget(Axis.vertical),
),
),
),
);
Widget _buildSliderRight() => widget.struct.fullScreen
? Container()
: Align(
alignment: Alignment.centerRight,
child: Material(
color: Color(0x0),
child: Container(
width: 35,
height: 300,
decoration: BoxDecoration(
color: Color(0x66000000),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
),
padding: EdgeInsets.only(top: 10, bottom: 10, left: 5, right: 6),
child: Center(
child: _buildSliderWidget(Axis.vertical),
),
),
),
);
Widget _buildSliderWidget(Axis axis) {
return FlutterSlider(
axis: axis,
values: [_slider.toDouble()], values: [_slider.toDouble()],
min: 0, min: 0,
max: (widget.struct.images.length - 1).toDouble(), max: (widget.struct.images.length - 1).toDouble(),
@ -406,10 +498,6 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
), ),
); );
}), }),
),
),
Expanded(child: Container()),
],
); );
} }
@ -427,7 +515,8 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
} }
Widget _buildFullScreenController() { Widget _buildFullScreenController() {
if (!widget.struct.fullScreen) { if (widget.readerSliderPosition == ReaderSliderPosition.BOTTOM &&
!widget.struct.fullScreen) {
return Container(); return Container();
} }
return Align( return Align(
@ -526,22 +615,10 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
]); ]);
break; break;
} }
return Container( return SizedBox(
width: constraints.maxWidth, width: constraints.maxWidth,
height: constraints.maxHeight, height: constraints.maxHeight,
child: Column( child: child,
children: [
Container(
height: widget.struct.fullScreen
? 0
: Scaffold.of(context).appBarMaxHeight ?? 0,
),
Expanded(child: child),
Container(
height: widget.struct.fullScreen ? 0 : 45,
),
],
),
); );
}, },
); );
@ -565,6 +642,10 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
} }
Future _onMoreSetting() async { Future _onMoreSetting() async {
//
final currentQuality = currentQualityCode();
final cReaderSliderPosition = currentReaderSliderPosition();
//
await showMaterialModalBottomSheet( await showMaterialModalBottomSheet(
context: context, context: context,
backgroundColor: Color(0xAA000000), backgroundColor: Color(0xAA000000),
@ -580,8 +661,9 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
); );
if (widget.pagerDirection != gReaderDirection || if (widget.pagerDirection != gReaderDirection ||
widget.pagerType != currentReaderType() || widget.pagerType != currentReaderType() ||
widget.currentQuality != currentQualityCode() || currentQuality != currentQualityCode() ||
widget.fullScreenAction != currentFullScreenAction()) { widget.fullScreenAction != currentFullScreenAction() ||
cReaderSliderPosition != currentReaderSliderPosition()) {
widget.struct.onReloadEp(); widget.struct.onReloadEp();
} }
} }
@ -599,13 +681,10 @@ abstract class _ImageReaderContentState extends State<_ImageReaderContent> {
bool _hasNextEp() => bool _hasNextEp() =>
widget.struct.epNameMap.containsKey(widget.struct.epOrder + 1); widget.struct.epNameMap.containsKey(widget.struct.epOrder + 1);
double _topBarHeight() { double _topBarHeight() => Scaffold.of(context).appBarMaxHeight ?? 0;
return Scaffold.of(context).appBarMaxHeight ?? 0;
}
double _bottomBarHeight() { double _bottomBarHeight() =>
return 45; widget.readerSliderPosition == ReaderSliderPosition.BOTTOM ? 45 : 0;
}
} }
class _EpChooser extends StatefulWidget { class _EpChooser extends StatefulWidget {
@ -740,6 +819,20 @@ class _SettingPanelState extends State<_SettingPanel> {
], ],
), ),
), ),
Row(
children: [
_bottomIcon(
icon: Icons.straighten_sharp,
title: currentReaderSliderPositionName(),
onPressed: () async {
await chooseReaderSliderPosition(context);
},
),
Expanded(child: Container()),
Expanded(child: Container()),
Expanded(child: Container()),
],
),
], ],
); );
} }
@ -1415,7 +1508,44 @@ class _GalleryReaderState extends _ImageReaderContentState {
), ),
child: gallery, child: gallery,
); );
return gallery; return Stack(
children: [
gallery,
_buildNextEpController(),
],
);
}
Widget _buildNextEpController() {
if (_current < widget.struct.images.length - 1) return Container();
return Align(
alignment: Alignment.bottomRight,
child: Material(
color: Color(0x0),
child: Container(
margin: EdgeInsets.only(bottom: 10),
padding: EdgeInsets.only(left: 10, right: 10, top: 4, bottom: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
color: Color(0x88000000),
),
child: GestureDetector(
onTap: () {
if (_hasNextEp()) {
_onNextAction();
} else {
Navigator.of(context).pop();
}
},
child: Text(_hasNextEp() ? '下一章' : '结束阅读',
style: TextStyle(color: Colors.white)),
),
),
),
);
} }
} }