pdf_bottom_annot_fun_widget.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_svg/flutter_svg.dart';
  3. import 'package:kmpdfkit_demo/widgets/contains.dart';
  4. import 'package:kmpdfkit_demo/widgets/events.dart';
  5. import 'package:kmpdfkit_demo/widgets/function/annot_attribute_options_widget.dart';
  6. import 'package:kmpdfkit_demo/widgets/function/attrwidget/signature/attr_signature_list_widget.dart';
  7. import 'package:kmpdfkit_demo/widgets/models/annot_attribute_bean.dart';
  8. import 'package:kmpdfkit_demo/widgets/models/annot_bean.dart';
  9. /// pdf_bottom_annot_fun_widget.dart
  10. ///
  11. /// Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  12. ///
  13. /// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  14. /// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  15. /// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  16. /// This notice may not be removed from this file.
  17. class PDFBottomAnnotFunWidget extends StatefulWidget {
  18. const PDFBottomAnnotFunWidget({Key? key}) : super(key: key);
  19. @override
  20. State<PDFBottomAnnotFunWidget> createState() =>
  21. _PDFBottomAnnotFunWidgetState();
  22. }
  23. class _PDFBottomAnnotFunWidgetState extends State<PDFBottomAnnotFunWidget> {
  24. AnnotationType selectAnnot = AnnotationType.unknown;
  25. var annotFunList = [
  26. AnnotBean(
  27. annotType: AnnotationType.highlight,
  28. normalImagePath: 'assets/images/ic_reader_highlight.svg',
  29. selectImagePath: 'assets/images/ic_reader_highlight_select.svg',
  30. attributeBean: AnnotAttributeBean(color: Colors.red),
  31. ),
  32. AnnotBean(
  33. annotType: AnnotationType.underline,
  34. normalImagePath: 'assets/images/ic_reader_underline.svg',
  35. selectImagePath: 'assets/images/ic_reader_underline_select.svg',
  36. attributeBean: AnnotAttributeBean(color: Colors.blue)),
  37. AnnotBean(
  38. annotType: AnnotationType.strikeout,
  39. normalImagePath: 'assets/images/ic_reader_strikethrough.svg',
  40. selectImagePath: 'assets/images/ic_reader_strikethrough_select.svg',
  41. attributeBean: AnnotAttributeBean(color: Colors.green)),
  42. AnnotBean(
  43. annotType: AnnotationType.squiggly,
  44. normalImagePath: 'assets/images/ic_reader_squiggly_underline.svg',
  45. selectImagePath:
  46. 'assets/images/ic_reader_squiggly_underline_select.svg',
  47. attributeBean: AnnotAttributeBean(color: Colors.pink)),
  48. AnnotBean(
  49. annotType: AnnotationType.ink,
  50. normalImagePath: 'assets/images/ic_reader_ink.svg',
  51. selectImagePath: 'assets/images/ic_reader_ink_select.svg',
  52. attributeBean: AnnotAttributeBean(color: Colors.yellow)),
  53. AnnotBean(
  54. annotType: AnnotationType.shape,
  55. normalImagePath: 'assets/images/ic_reader_shape.svg',
  56. selectImagePath: 'assets/images/ic_reader_shape_select.svg',
  57. attributeBean: AnnotAttributeBean(color: Colors.transparent)),
  58. AnnotBean(
  59. annotType: AnnotationType.freetext,
  60. normalImagePath: 'assets/images/ic_reader_freetext.svg',
  61. selectImagePath: 'assets/images/ic_reader_freetext_select.svg',
  62. attributeBean: AnnotAttributeBean(color: Colors.transparent)),
  63. AnnotBean(
  64. annotType: AnnotationType.signature,
  65. normalImagePath: 'assets/images/ic_reader_signature.svg',
  66. selectImagePath: 'assets/images/ic_reader_signature_select.svg',
  67. attributeBean: AnnotAttributeBean(
  68. color: Colors.transparent, shapeType: AnnotationType.signature)),
  69. AnnotBean(
  70. annotType: AnnotationType.stamp,
  71. normalImagePath: 'assets/images/ic_reader_stamp.svg',
  72. selectImagePath: 'assets/images/ic_reader_stamp_select.svg',
  73. attributeBean: AnnotAttributeBean(
  74. color: Colors.transparent, shapeType: AnnotationType.stamp)),
  75. AnnotBean(
  76. annotType: AnnotationType.link,
  77. normalImagePath: 'assets/images/ic_reader_link.svg',
  78. selectImagePath: 'assets/images/ic_reader_link_select.svg',
  79. attributeBean: AnnotAttributeBean(
  80. color: Colors.transparent, shapeType: AnnotationType.link)),
  81. AnnotBean(
  82. annotType: AnnotationType.redact,
  83. normalImagePath: 'assets/images/ic_reader_redact.svg',
  84. selectImagePath: 'assets/images/ic_reader_redact_select.svg',
  85. attributeBean: AnnotAttributeBean(
  86. color: Colors.transparent, shapeType: AnnotationType.redact)),
  87. ];
  88. @override
  89. void initState() {
  90. super.initState();
  91. initAnnotAttr();
  92. setReaderViewContextMenuHelperListener((annotBean) {
  93. _attributeOptionsModalBottomSheet(context, annotBean,
  94. (AnnotAttributeBean bean) {
  95. modifyAnnotationAttribute(
  96. annotationType: annotBean.annotType, bean: bean);
  97. }, () {
  98. dismissModifyAnnotationAttribute();
  99. });
  100. });
  101. setReaderViewFocusedChangeListener((annotationType) {
  102. if (selectAnnot != annotationType) {
  103. setState(() {
  104. selectAnnot = annotationType;
  105. });
  106. }
  107. });
  108. }
  109. @override
  110. Widget build(BuildContext context) {
  111. return annotFunctionMenuListWidget(selectAnnot, (annotBean) {
  112. var annot = selectAnnot == annotBean.annotType
  113. ? AnnotationType.unknown
  114. : annotBean.attributeBean.shapeType;
  115. setCPDFReaderViewFocusType(annot);
  116. setState(() {
  117. selectAnnot = selectAnnot == annotBean.annotType
  118. ? AnnotationType.unknown
  119. : annotBean.annotType;
  120. });
  121. if (selectAnnot == AnnotationType.signature ||
  122. selectAnnot == AnnotationType.stamp) {
  123. showAttributeModalBottomSheet(context, annotBean);
  124. }
  125. }, (annotBean) {
  126. setCPDFReaderViewFocusType(annotBean.attributeBean.shapeType);
  127. setState(() {
  128. selectAnnot = annotBean.annotType;
  129. });
  130. if(selectAnnot != AnnotationType.link && selectAnnot != AnnotationType.redact){
  131. showAttributeModalBottomSheet(context, annotBean);
  132. }
  133. });
  134. }
  135. Widget annotFunctionMenuListWidget(
  136. AnnotationType selectAnnotType,
  137. Function(AnnotBean annotBean) onTap,
  138. Function(AnnotBean annotBean) onLongPress) {
  139. return Container(
  140. color: const Color(0xFFEFF4FD),
  141. height: 60,
  142. alignment: Alignment.centerLeft,
  143. child: ListView.builder(
  144. itemCount: annotFunList.length,
  145. scrollDirection: Axis.horizontal,
  146. primary: true,
  147. shrinkWrap: true,
  148. itemBuilder: (context, index) {
  149. AnnotBean bean = annotFunList[index];
  150. return Container(
  151. width: 60,
  152. padding: const EdgeInsets.all(16),
  153. height: 60,
  154. color: selectAnnotType == bean.annotType
  155. ? const Color(0xFFD5E3FE)
  156. : Colors.transparent,
  157. child: InkWell(
  158. onTap: () {
  159. onTap(bean);
  160. },
  161. onLongPress: () {
  162. onLongPress(bean);
  163. },
  164. child: Stack(
  165. children: [
  166. Positioned(
  167. top: 0,
  168. bottom: 0,
  169. left: 0,
  170. right: 0,
  171. child: Container(
  172. margin: const EdgeInsets.all(2),
  173. color: bean.attributeBean.color,
  174. width: double.infinity,
  175. height: double.infinity,
  176. ),
  177. ),
  178. Positioned(
  179. top: 0,
  180. bottom: 0,
  181. left: 0,
  182. right: 0,
  183. child: SvgPicture.asset(
  184. selectAnnotType == bean.annotType
  185. ? bean.selectImagePath!
  186. : bean.normalImagePath!,
  187. semanticsLabel: bean.annotType.name,
  188. ))
  189. ],
  190. ),
  191. ),
  192. );
  193. }));
  194. }
  195. void showAttributeModalBottomSheet(
  196. BuildContext context, AnnotBean annotBean) {
  197. _attributeOptionsModalBottomSheet(context, annotBean,
  198. (AnnotAttributeBean attributeBean) async {
  199. setAnnotAttribute(
  200. annotationType: annotBean.annotType, bean: attributeBean);
  201. AnnotBean bean = annotFunList
  202. .firstWhere((element) => element.annotType == annotBean.annotType);
  203. setState(() {
  204. bean.attributeBean = attributeBean;
  205. });
  206. }, () {
  207. setState(() {
  208. if (selectAnnot == AnnotationType.signature ||
  209. selectAnnot == AnnotationType.stamp) {
  210. selectAnnot = AnnotationType.unknown;
  211. setCPDFReaderViewFocusType(selectAnnot);
  212. }
  213. });
  214. });
  215. }
  216. void _attributeOptionsModalBottomSheet(context, AnnotBean annotBean,
  217. AnnotAttributeOptionsCallback callback, VoidCallback? closeCallback) {
  218. if (annotBean.annotType == AnnotationType.link) {
  219. Future<void> close = showDialog(
  220. context: context,
  221. builder: (context) {
  222. return AnnotAttributeOptionsWidget(
  223. attributeOptionsCallback: callback,
  224. annotBean: annotBean,
  225. );
  226. });
  227. close.then((value) {
  228. if (closeCallback != null) {
  229. closeCallback();
  230. }
  231. });
  232. } else {
  233. Future<void> close = showModalBottomSheet<int>(
  234. context: context,
  235. barrierColor: Colors.transparent,
  236. isScrollControlled: true,
  237. useSafeArea: true,
  238. builder: (BuildContext context) {
  239. return AnnotAttributeOptionsWidget(
  240. attributeOptionsCallback: callback,
  241. annotBean: annotBean,
  242. );
  243. });
  244. close.then((value) {
  245. if (closeCallback != null) {
  246. closeCallback();
  247. }
  248. });
  249. }
  250. }
  251. void initAnnotAttr() async {
  252. AnnotAttributeBean highlight =
  253. await getAnnotAttribute(AnnotationType.highlight);
  254. AnnotAttributeBean underline =
  255. await getAnnotAttribute(AnnotationType.underline);
  256. AnnotAttributeBean strikeout =
  257. await getAnnotAttribute(AnnotationType.strikeout);
  258. AnnotAttributeBean squiggly =
  259. await getAnnotAttribute(AnnotationType.squiggly);
  260. AnnotAttributeBean ink = await getAnnotAttribute(AnnotationType.ink);
  261. AnnotAttributeBean shape = await getAnnotAttribute(AnnotationType.shape);
  262. AnnotAttributeBean freeText =
  263. await getAnnotAttribute(AnnotationType.freetext);
  264. setState(() {
  265. for (var element in annotFunList) {
  266. switch (element.annotType) {
  267. case AnnotationType.highlight:
  268. element.attributeBean = highlight;
  269. break;
  270. case AnnotationType.underline:
  271. element.attributeBean = underline;
  272. break;
  273. case AnnotationType.strikeout:
  274. element.attributeBean = strikeout;
  275. break;
  276. case AnnotationType.squiggly:
  277. element.attributeBean = squiggly;
  278. break;
  279. case AnnotationType.unknown:
  280. break;
  281. case AnnotationType.ink:
  282. element.attributeBean = ink;
  283. break;
  284. case AnnotationType.shape:
  285. element.attributeBean = shape;
  286. break;
  287. case AnnotationType.freetext:
  288. element.attributeBean = freeText;
  289. break;
  290. default:
  291. break;
  292. }
  293. }
  294. });
  295. }
  296. }