cpdf_thumbnail_page.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import 'dart:typed_data';
  2. import 'package:compdfkit_flutter/core/document/cpdf_document.dart';
  3. import 'package:flutter/material.dart';
  4. /// Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  5. ///
  6. /// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  7. /// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  8. /// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  9. /// This notice may not be removed from this file.
  10. class CPDFThumbnailPage extends StatefulWidget {
  11. final CPDFDocument document;
  12. final int currentPageIndex;
  13. const CPDFThumbnailPage(
  14. {Key? key, required this.document, required this.currentPageIndex})
  15. : super(key: key);
  16. @override
  17. State<CPDFThumbnailPage> createState() => _CPDFThumbnailPageState();
  18. }
  19. class _CPDFThumbnailPageState extends State<CPDFThumbnailPage> {
  20. final ScrollController _scrollController = ScrollController();
  21. final GlobalKey globalKey = GlobalKey();
  22. @override
  23. void initState() {
  24. super.initState();
  25. // WidgetsBinding.instance.addPostFrameCallback((_) {
  26. // scrollToItem(widget.currentPageIndex);
  27. // });
  28. }
  29. @override
  30. void dispose() {
  31. super.dispose();
  32. _scrollController.dispose();
  33. }
  34. @override
  35. Widget build(BuildContext context) {
  36. return FutureBuilder(
  37. initialData: 0,
  38. future: widget.document.getPageCount(),
  39. builder: (context, snapshot) {
  40. final size = MediaQuery.of(context).size;
  41. final widgetWidth = size.width - 16;
  42. return OrientationBuilder(builder: (context, orientation) {
  43. int crossAxisCount =
  44. orientation == Orientation.portrait ? 3 : 6;
  45. return GridView.builder(
  46. padding: const EdgeInsets.symmetric(horizontal: 8),
  47. key: globalKey,
  48. controller: _scrollController,
  49. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  50. crossAxisCount: crossAxisCount,
  51. mainAxisSpacing: 8,
  52. crossAxisSpacing: 8,
  53. childAspectRatio: 0.62),
  54. itemCount: snapshot.data ?? 0,
  55. itemBuilder: (context, index) => Padding(
  56. padding: const EdgeInsets.only(top: 8),
  57. child: _thumbnailItem(
  58. index, ((widgetWidth - 22) / crossAxisCount)),
  59. ));
  60. });
  61. });
  62. }
  63. Widget _thumbnailItem(int index, double itemWidth) {
  64. double aspectRatio = 0.30;
  65. double itemHeight = itemWidth + (itemWidth * aspectRatio);
  66. bool selected = widget.currentPageIndex == index;
  67. return FutureBuilder(
  68. future: widget.document.getPageSize(index),
  69. builder: (context, snap) {
  70. if (snap.connectionState == ConnectionState.done && snap.hasData) {
  71. var size = snap.data!;
  72. var imageWidth = itemWidth;
  73. var imageHeight = (imageWidth / size[0]) * size[1];
  74. if (imageHeight > itemHeight) {
  75. imageHeight = itemHeight;
  76. imageWidth = (imageHeight / size[1]) * size[0];
  77. }
  78. return Column(
  79. mainAxisAlignment: MainAxisAlignment.center,
  80. children: [
  81. InkWell(
  82. child: FutureBuilder(
  83. future: widget.document.renderPageAtIndex(
  84. index, imageWidth.toInt(), imageHeight.toInt()),
  85. builder: (context, snapshot) {
  86. if (snapshot.connectionState == ConnectionState.done &&
  87. !snapshot.hasError) {
  88. Uint8List? imageData = snapshot.data;
  89. if (imageData != null) {
  90. return _imageItem(
  91. Image.memory(
  92. imageData,
  93. ),
  94. selected,
  95. imageWidth,
  96. imageHeight);
  97. } else {
  98. return const Padding(padding: EdgeInsets.zero);
  99. }
  100. } else {
  101. return const Padding(padding: EdgeInsets.zero);
  102. }
  103. }),
  104. onTap: () {
  105. Navigator.pop(context, index);
  106. },
  107. ),
  108. _pageIndicator(index, selected)
  109. ],
  110. );
  111. } else {
  112. return const Padding(padding: EdgeInsets.zero);
  113. }
  114. });
  115. }
  116. Widget _imageItem(
  117. Widget child, bool selected, double imageWidth, double imageHeight) {
  118. return Container(
  119. width: imageWidth,
  120. height: imageHeight,
  121. decoration: BoxDecoration(
  122. border: Border.all(
  123. color: selected
  124. ? Theme.of(context).colorScheme.primaryContainer
  125. : const Color(0xFFDDE9FF),
  126. width: 2),
  127. borderRadius: const BorderRadius.all(Radius.circular(2))),
  128. child: child,
  129. );
  130. }
  131. Widget _pageIndicator(int index, bool selected){
  132. return Container(
  133. margin: const EdgeInsets.only(top: 8),
  134. decoration: BoxDecoration(
  135. color: selected
  136. ? Theme.of(context).colorScheme.primaryContainer
  137. : Colors.transparent,
  138. borderRadius:
  139. const BorderRadius.all(Radius.circular(2))),
  140. child: Padding(
  141. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2),
  142. child: Text(
  143. (index + 1).toString(),
  144. style: TextStyle(
  145. fontSize: 12,
  146. color: selected ? Colors.white : Colors.black),
  147. ),
  148. ));
  149. }
  150. // Function to scroll to a specific item in the GridView
  151. void scrollToItem(int index) {
  152. // _scrollController.animateTo(
  153. // offset,
  154. // duration: const Duration(milliseconds: 500),
  155. // curve: Curves.fastOutSlowIn,
  156. // );
  157. }
  158. }