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];
}