|
@@ -0,0 +1,132 @@
|
|
|
+import 'dart:async';
|
|
|
+
|
|
|
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+
|
|
|
+import '../dialog/cpdf_base_input_dialog_widget.dart';
|
|
|
+
|
|
|
+
|
|
|
+/// Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
|
|
|
+///
|
|
|
+/// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
|
|
|
+/// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
|
|
|
+/// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
|
|
|
+/// This notice may not be removed from this file.
|
|
|
+
|
|
|
+class CPDFPageIndicator extends StatefulWidget {
|
|
|
+ final CPDFViewCtrl ctrl;
|
|
|
+
|
|
|
+ Decoration? decoration;
|
|
|
+
|
|
|
+ TextStyle? textStyle;
|
|
|
+
|
|
|
+ bool alwaysShow;
|
|
|
+
|
|
|
+ CPDFPageIndicator(
|
|
|
+ {required this.ctrl,
|
|
|
+ this.decoration,
|
|
|
+ this.textStyle,
|
|
|
+ this.alwaysShow = false,
|
|
|
+ super.key}) {
|
|
|
+ decoration ??= const BoxDecoration(
|
|
|
+ color: Color(0xCC000000),
|
|
|
+ borderRadius: BorderRadius.all(Radius.circular(2)));
|
|
|
+ textStyle ??= const TextStyle(color: Colors.white, fontSize: 12);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ State<CPDFPageIndicator> createState() => _CPDFPageIndicatorState();
|
|
|
+}
|
|
|
+
|
|
|
+class _CPDFPageIndicatorState extends State<CPDFPageIndicator> {
|
|
|
+ int _pageCount = 0;
|
|
|
+
|
|
|
+ Timer? _timer;
|
|
|
+
|
|
|
+ bool _showIndicator = true;
|
|
|
+
|
|
|
+ @override
|
|
|
+ void initState() {
|
|
|
+ super.initState();
|
|
|
+ _initDocumentData();
|
|
|
+ }
|
|
|
+
|
|
|
+ void _initDocumentData() async {
|
|
|
+ widget.ctrl.document.getPageCount().then((value) {
|
|
|
+ setState(() {
|
|
|
+ _pageCount = value;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ if (!widget.alwaysShow) {
|
|
|
+ widget.ctrl.scrollStatusController.stream.listen((event) {
|
|
|
+ if (event) {
|
|
|
+ if (!_showIndicator) {
|
|
|
+ setState(() {
|
|
|
+ _timer?.cancel();
|
|
|
+ _showIndicator = event;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ handleScrollEnd();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void dispose() {
|
|
|
+ super.dispose();
|
|
|
+ _timer?.cancel();
|
|
|
+ }
|
|
|
+
|
|
|
+ void handleScrollEnd() {
|
|
|
+ _timer?.cancel();
|
|
|
+ _timer = Timer(const Duration(seconds: 3), () {
|
|
|
+ setState(() {
|
|
|
+ _showIndicator = false;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ return AnimatedOpacity(
|
|
|
+ opacity: _showIndicator ? 1.0 : 0.0,
|
|
|
+ duration: const Duration(milliseconds: 200),
|
|
|
+ child: GestureDetector(
|
|
|
+ child: Container(
|
|
|
+ constraints: BoxConstraints(minWidth: 50),
|
|
|
+ decoration: widget.decoration,
|
|
|
+ padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
+ children: [
|
|
|
+ StreamBuilder(
|
|
|
+ initialData: 0,
|
|
|
+ stream: widget.ctrl.currentPageIndexStream.stream,
|
|
|
+ builder: (context, pageIndex) {
|
|
|
+ return Text((pageIndex.data! + 1).toString(),
|
|
|
+ style: widget.textStyle);
|
|
|
+ }),
|
|
|
+ Text('/', style: widget.textStyle),
|
|
|
+ Text(_pageCount.toString(), style: widget.textStyle)
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ onTap: () async {
|
|
|
+ int? jumpPageIndex = await showDialog<int?>(
|
|
|
+ context: context,
|
|
|
+ builder: (BuildContext context) {
|
|
|
+ return CPDFPageNavigationWidget(
|
|
|
+ pageCount: _pageCount,
|
|
|
+ hintText: 'Page (1/$_pageCount)',
|
|
|
+ );
|
|
|
+ });
|
|
|
+ if (jumpPageIndex != null) {
|
|
|
+ widget.ctrl.setDisplayPageIndex(jumpPageIndex);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ));
|
|
|
+ }
|
|
|
+}
|