import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:kmpdfkit_demo/widgets/contains.dart'; import 'package:kmpdfkit_demo/widgets/extension/color_extension.dart'; import 'package:kmpdfkit_demo/widgets/models/annot_bean.dart'; import 'models/annot_attribute_bean.dart'; const _methodChannel = MethodChannel(ChannelNames.eventCPDFReaderView); const _modifyAnnotAttrChannel = MethodChannel(ChannelNames.eventModifyAnnotationAttr); //Listen to PDFReaderView events. const _readerViewCallBackEventChannel = EventChannel(ChannelNames.eventReaderViewCallback); const _contextMenuHelperEventChannel = EventChannel(ChannelNames.eventReaderViewContextMenuHelper); const _focusedChangeEventChannel = EventChannel(ChannelNames.eventFocusedChange); typedef CancelListener = void Function(); enum eventSinkId { readerViewCallBack, readerViewContextMenuHelper, readerViewFocusedChange } /// Listen to PDFReaderView events
/// onTapMainDocArea : Click CPDFReaderView display area callback /// onMoveToChild : The pdf document is moved to the specified page, and the page number is returned by 'pageIndex' /// onRecordLastJumpNum : Returns the page number of the last record and returns the page number via the 'pageIndex' parameter /// onScrolling : CPDFReaderView page sliding monitoring /// onScrollEnd : CPDFReaderView page sliding end monitoring /// ///Please use in addOnPlatformViewCreatedListener ///```dart /// ..addOnPlatformViewCreatedListener((id) { /// setReaderViewCallbackListener( /// onTapMainDocArea: () { /// print("onTapMainDocArea"); /// }, /// onMoveToChild: (pageIndex) {}, /// onScrolling: () {}, /// onScrollEnd: () {}, /// onRecordLastJumpPageNum: (pageIndex) {}); /// }) ///``` /// CancelListener setReaderViewCallbackListener( {VoidCallback? onTapMainDocArea, Function(int pageIndex)? onMoveToChild, VoidCallback? onScrolling, VoidCallback? onScrollEnd, Function(int pageIndex)? onRecordLastJumpPageNum}) { var subscription = _readerViewCallBackEventChannel .receiveBroadcastStream(eventSinkId.readerViewCallBack.index) .listen((data) { Map result = data; String eventType = result[EventParameters.eventType]; switch (eventType) { case EventParameters.onTapMainDocArea: if (onTapMainDocArea != null) { onTapMainDocArea(); } break; case EventParameters.onMoveToChild: if (onMoveToChild != null) { int pageIndex = result[EventParameters.pageIndex]; onMoveToChild(pageIndex); } break; case EventParameters.onRecordLastJumpPageNum: if (onRecordLastJumpPageNum != null) { int pageIndex = result[EventParameters.pageIndex]; onRecordLastJumpPageNum(pageIndex); } break; case EventParameters.onScrollEnd: if (onScrollEnd != null) { onScrollEnd(); } break; case EventParameters.onScrolling: if (onScrolling != null) { onScrolling(); } break; default: break; } }, cancelOnError: true); return () { subscription.cancel(); }; } /// Set up an event channel for "cpdfreaderview" to trigger an event when the user clicks on the "Properties" menu item. /// When the event is triggered, the native side will return the selected annotation type and related properties. /// The Flutter side will display an annotation property adjustment interface /// based on the returned annotation type and properties, allowing users to modify the annotation properties. /// After modifying the annotation properties, the Flutter side will /// send the modified property values back to the native side to update /// the annotation in the PDF file. /// ```dart /// setReaderViewContextMenuHelperListener((annotBean) { /// //show annotation attribute options widget /// _showAttributeOptionsModalBottomSheet(context, annotBean,(AnnotAttributeBean bean) { /// modifyAnnotationAttribute( /// annotationType: annotBean.annotType, bean: bean); /// }, (){ /// dismissModifyAnnotationAttribute(); /// }); /// }); /// /// ``` void setReaderViewContextMenuHelperListener( Function(AnnotBean) showAnnotationAttributeOptions) { _contextMenuHelperEventChannel.receiveBroadcastStream({ EventParameters.eventType: eventSinkId.readerViewContextMenuHelper.name }).listen((event) { Map result = event; String annotType = result[EventParameters.annotType]; print('setReaderViewContextMenuHelperListener:$event'); AnnotationType type = AnnotationType.values.byName(annotType); showAnnotationAttributeOptions(AnnotBean( annotType: type, attributeBean: AnnotAttributeBean.parseMapValue(type, result), )); }, cancelOnError: true); } ///Converts the focused type from a string to an AnnotationType enum value. void setReaderViewFocusedChangeListener(Function(AnnotationType) callback) { _focusedChangeEventChannel .receiveBroadcastStream(eventSinkId.readerViewFocusedChange.name) .listen((event) { String focusedType = event; //Converts the focused type from a string to an AnnotationType enum value. AnnotationType type = AnnotationType.values.byName(focusedType.toLowerCase()); // If the focused type is a shape type, treat it as a general shape type. if(type.isShapeType){ type = AnnotationType.shape; } // Calls the callback function with the determined AnnotationType value. callback(type); }, cancelOnError: true); } ///This method is used to select annotations on the page and adjust their properties. /// Before using this method, please make sure that an annotation object has been selected. /// To use this method, you need to first call the "setReaderViewContextMenuHelperListener" method to set up the context menu. /// ```dart /// setReaderViewContextMenuHelperListener((annotBean) { /// //show annotation attribute options widget /// _showAttributeOptionsModalBottomSheet(context, annotBean,(AnnotAttributeBean bean) { /// //modify annotation attribute /// modifyAnnotationAttribute( /// annotationType: annotBean.annotType, bean: bean); /// }, (){ /// dismissModifyAnnotationAttribute(); /// }); /// }); /// /// ``` void modifyAnnotationAttribute( {required AnnotationType annotationType, required AnnotAttributeBean bean}) async { await _modifyAnnotAttrChannel.invokeMethod( Functions.modifyAnnotAttribute, bean.toMapValues(annotationType)); } /// Please call this method after the annotation attribute adjustment interface is closed. void dismissModifyAnnotationAttribute() async { await _modifyAnnotAttrChannel .invokeMethod(Functions.dismissModifyAnnotationAttr); } ///get current CPDFReaderView scroll direction ///true : [ScrollDirection.vertical] ///false : [ScrollDirection.horizontal] ///```dart /// bool isVertical = await scrollDirectionIsVerticalMode(); /// ``` Future scrollDirectionIsVerticalMode() async { String scrollDirection = await _methodChannel.invokeMethod(Functions.getScrollDirection); return scrollDirection == ScrollDirection.vertical; } /// set CPDFReaderView scroll direction ///```dart ///bool isVertical = await setScrollDirection(direction); /// ///``` /// Returns the current scroll direction /// true : [ScrollDirection.vertical] /// false : [ScrollDirection.horizontal] /// Future setScrollDirection(String direction) async { String scrollDirection = await _methodChannel.invokeMethod( Functions.setScrollDirection, {EventParameters.scrollDirection: direction}); return scrollDirection == ScrollDirection.vertical; } ///Get the current CPDFReaderView page mode ///```dart /// bool doublePage = await isDoublePage(); /// ///``` Future isDoublePage() async { return await _methodChannel.invokeMethod(Functions.getPageMode); } ///set page mode ///true: double page ///false: single page ///```dart /// bool isDoublePage = await setPageMode(doublePage); /// ///``` Future setPageMode(bool doublePage) async { return await _methodChannel.invokeMethod( Functions.setPageMode, {EventParameters.isDoublePage: doublePage}); } ///Get whether 'CPDFReaderView' is in continuous scrolling mode ///```dart /// bool isContinue = await isContinueMode(); /// ``` Future isContinueMode() async { return await _methodChannel.invokeMethod(Functions.getPageContinue); } ///Set page scrolling mode ///true: continue Mode ///```dart /// bool isContinueMode = await setIsContinueMode(isContinueMode); /// ``` Future setIsContinueMode(bool isContinueMode) async { return await _methodChannel.invokeMethod(Functions.setPageContinue, {EventParameters.isContinueMode: isContinueMode}); } ///Get whether 'ComPDFReaderView' is in cover display mode ///```dart /// bool isCoverPageMode = await isCoverPageMode(); /// ``` Future isCoverPageMode() async { return await _methodChannel.invokeMethod(Functions.isCoverPageMode); } ///set is cover display mode ///true: is cover page mode ///```dart /// bool isCoverPageMode = await setIsCoverPageMode(isCoverPageMode); /// ``` Future setIsCoverPageMode(bool isCoverPageMode) async { return await _methodChannel.invokeMethod(Functions.setCoverPageMode, {EventParameters.isCoverPageMode: isCoverPageMode}); } ///Get 'ComPDFReaderView' whether to crop the display mode ///```dart /// bool isCropMode = await isCropPageMode(); /// ``` Future isCropPageMode() async { return await _methodChannel.invokeMethod(Functions.isCropPageMode); } ///set is crop display mode ///true: is crop page mode ///```dart /// bool isCropMode = await setIsCropPageMode(isCropPageMode); /// ``` Future setIsCropPageMode(bool isCropPageMode) async { return await _methodChannel.invokeMethod(Functions.setIsCropPageMode, {EventParameters.isCropPageMode: isCropPageMode}); } /// get reader view background color ///```dart /// int color = await getReadBackgroundColor(); ///``` /// return current reader view background color Future getReadBackgroundColor() async { return await _methodChannel.invokeMethod(Functions.getReadBackgroundColor); } /// set reader view background color /// Changing the appearance mode will change the PDF rendering style, but it does not modify the PDF on disk. To set the color mode: /// normal color mode : #FFFFFF /// Dark mode : #000000 /// Sepia mode : #FFEFBE /// Reseda mode : #CDE6D0 /// Custom color mode : any hexadecimal value ///```dart /// int color = await setReadBackgroundColor(backgroundColor); /// ///``` ///return current reader view background color Future setReadBackgroundColor(int backgroundColor) async { return await _methodChannel.invokeMethod(Functions.setReadBackgroundColor, {EventParameters.readBackgroundColor: backgroundColor}); } /// Get annotation attributes based on annotation type /// /// ```dart /// AnnotAttributeBean highlight = await getAnnotAttribute(AnnotType.highlight); /// ``` /// return annotation attributes color and alpha Future getAnnotAttribute(AnnotationType annotType) async { Map annotAttrMap = await _methodChannel.invokeMethod( Functions.getAnnotAttribute, {EventParameters.annotType: annotType.name}); return AnnotAttributeBean.parseMapValue(annotType, annotAttrMap) ..showShapeTypeWidget = true; } ///set annotation attributes ///```dart /// AnnotAttributeBean attr = await setAnnotAttribute( /// annotType: annotBean.annotType, color: color, alpha: alpha); ///``` /// return annotation attributes color and alpha void setAnnotAttribute( {required AnnotationType annotationType, required AnnotAttributeBean bean}) async { await _methodChannel.invokeMethod(Functions.setAnnotAttribute, { EventParameters.annotType: annotationType.name, EventParameters.annotAttribute: bean.toMapValues(annotationType) }); } /// set CPDFReaderView current focused type /// This setting will change the type of action you swipe on CPDFReaderView /// If you need to set it as a browsing state, please set /// focusedType :[AnnotationType.unknown] /// touchMode : [TouchMode.browse] /// /// If you need to set to add Annotation state, please set /// focusedType : [AnnotationType] /// touchMode : [TouchMode.add_annot] ///```dart /// setCPDFReaderViewFocusType(annotationType) ///``` /// void setCPDFReaderViewFocusType(AnnotationType annotationType) async { await _methodChannel.invokeMethod(Functions.setCurrentFocusedType, { EventParameters.touchMode: annotationType == AnnotationType.unknown ? TouchMode.browse.name : TouchMode.add_annot.name, EventParameters.focusedType: annotationType.name }); } /// get pdf document file page total count Future getDocumentPageCount() async{ Map map = await _methodChannel.invokeMethod(Functions.getDocumentPageInfo); return map[EventParameters.documentPageCount]; }