From 68fd4387c1014aaf1311c7bf20803da892c91e7d Mon Sep 17 00:00:00 2001 From: Terry Yoon <104788313+terryyoon-pdftron@users.noreply.github.com> Date: Thu, 30 Jun 2022 12:26:16 -0700 Subject: [PATCH] Override toolbar button press CPM-23 (#572) * boilerplate code * android implementation * ios implementation * updated API.md * Updating package version * revised API.md, added null check * Updating package.json * Updating package version * revised ios implementation * Updating package version Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- API.md | 43 +++++++++++++++ .../pdftron/reactnative/utils/Constants.java | 1 + .../viewmanagers/DocumentViewViewManager.java | 5 ++ .../reactnative/views/DocumentView.java | 55 +++++++++++++++++++ .../RNTPTDocumentViewController.h | 2 + ios/RNTPTDocumentView.h | 4 ++ ios/RNTPTDocumentView.m | 40 ++++++++++++++ ios/RNTPTDocumentViewManager.m | 17 ++++++ lib/src/DocumentView/DocumentView.js | 9 +++ package.json | 2 +- src/DocumentView/DocumentView.tsx | 8 +++ 11 files changed, 185 insertions(+), 1 deletion(-) diff --git a/API.md b/API.md index 18954886c..3cb396db7 100644 --- a/API.md +++ b/API.md @@ -853,6 +853,49 @@ Defines whether the viewer will add padding to take account of the system status /> ``` +#### overrideToolbarButtonBehavior +array of [`Config.Buttons`](./src/Config/Config.ts) constants, optional, defaults to none + +Defines the option buttons in the top app nav bar or the bottom toolbar that will skip default behavior when pressed. +They will still be displayed in the toolbar, and the function [`onToolbarButtonPress`](#ontoolbarbuttonpress) will be called where custom behavior can be implemented. + +```js + { + if (id === Config.Buttons.shareButton) { + console.log('Share button pressed'); + } else if (id === Config.Buttons.searchButton) { + console.log('Search button pressed'); + } + }} +/> +``` + +#### onToolbarButtonPress +function, optional + +This function is called when a toolbar item passed in to [`overrideToolbarButtonBehavior`](#overridetoolbarbuttonbehavior) is pressed. + +Parameters: + +Name | Type | Description +--- | --- | --- +id | string | one of [`Config.Buttons`](./src/Config/Config.ts) constants representing the item that has been pressed + +```js + { + if (id === Config.Buttons.shareButton) { + console.log('Share button pressed'); + } else if (id === Config.Buttons.searchButton) { + console.log('Search button pressed'); + } + }} +/> +``` + ### Layout #### fitMode diff --git a/android/src/main/java/com/pdftron/reactnative/utils/Constants.java b/android/src/main/java/com/pdftron/reactnative/utils/Constants.java index 0d2051235..70e64be40 100644 --- a/android/src/main/java/com/pdftron/reactnative/utils/Constants.java +++ b/android/src/main/java/com/pdftron/reactnative/utils/Constants.java @@ -30,6 +30,7 @@ public final class Constants { public static final String ON_ANNOTATION_FLATTENED = "onAnnotationFlattened"; public static final String ON_ANNOTATION_TOOLBAR_ITEM_PRESS = "onAnnotationToolbarItemPress"; public static final String ON_SAVED_SIGNATURES_CHANGED = "onSavedSignaturesChanged"; + public static final String ON_TOOLBAR_BUTTON_PRESS = "onToolbarButtonPress"; // BUTTONS public static final String BUTTON_TOOLS = "toolsButton"; diff --git a/android/src/main/java/com/pdftron/reactnative/viewmanagers/DocumentViewViewManager.java b/android/src/main/java/com/pdftron/reactnative/viewmanagers/DocumentViewViewManager.java index 94bfee69f..faa419b71 100644 --- a/android/src/main/java/com/pdftron/reactnative/viewmanagers/DocumentViewViewManager.java +++ b/android/src/main/java/com/pdftron/reactnative/viewmanagers/DocumentViewViewManager.java @@ -526,6 +526,11 @@ public void setMaxSignatureCount(DocumentView documentView, int maxSignatureCoun SignatureDialogFragment.MAX_SIGNATURES = maxSignatureCount; } + @ReactProp(name = "overrideToolbarButtonBehavior") + public void setOverrideToolbarButtonBehavior(DocumentView documentView, @NonNull ReadableArray items) { + documentView.setOverrideToolbarButtonBehavior(items); + } + public void importBookmarkJson(int tag, String bookmarkJson) throws PDFNetException { DocumentView documentView = mDocumentViews.get(tag); if (documentView != null) { diff --git a/android/src/main/java/com/pdftron/reactnative/views/DocumentView.java b/android/src/main/java/com/pdftron/reactnative/views/DocumentView.java index 261c24a4c..86f4a4ac5 100644 --- a/android/src/main/java/com/pdftron/reactnative/views/DocumentView.java +++ b/android/src/main/java/com/pdftron/reactnative/views/DocumentView.java @@ -154,6 +154,9 @@ public class DocumentView extends com.pdftron.pdf.controls.DocumentView2 { private PDFViewCtrl.AnnotationManagerMode mAnnotationManagerUndoMode = PDFViewCtrl.AnnotationManagerMode.ADMIN_UNDO_OWN; private File mCollabTempFile; + // toolbar buttons + private ArrayList mToolbarOverrideButtons; + // quick menu private ArrayList mAnnotMenuItems; private ArrayList mAnnotMenuOverrideItems; @@ -713,6 +716,10 @@ public void setOverrideBehavior(@NonNull ReadableArray items) { } } + public void setOverrideToolbarButtonBehavior(ReadableArray items) { + mToolbarOverrideButtons = items != null ? items.toArrayList() : null; + } + public void setSignSignatureFieldsWithStamps(boolean signWithStamps) { mSignWithStamps = signWithStamps; } @@ -1674,6 +1681,44 @@ private TopToolbarMenuId convButtonIdToMenuId(String item) { return null; } + @Nullable + private String convItemIdToString(int id) { + String buttonId = null; + if (id == R.id.action_tabs) { + buttonId = BUTTON_TABS; + } else if (id == R.id.action_search) { + buttonId = BUTTON_SEARCH; + } else if (id == R.id.action_viewmode) { + buttonId = BUTTON_VIEW_CONTROLS; + } else if (id == R.id.action_thumbnails) { + buttonId = BUTTON_THUMBNAILS; + } else if (id == R.id.action_outline) { + buttonId = BUTTON_OUTLINE_LIST; + } else if (id == R.id.undo) { + buttonId = BUTTON_UNDO; + } else if (id == R.id.action_share) { + buttonId = BUTTON_SHARE; + } else if (id == R.id.action_reflow_mode) { + buttonId = BUTTON_REFLOW; + } else if (id == R.id.action_editpages) { + buttonId = BUTTON_EDIT_PAGES; + } else if (id == R.id.action_export_options) { + buttonId = BUTTON_SAVE_COPY; + } else if (id == R.id.action_print) { + buttonId = BUTTON_PRINT; + } else if (id == R.id.action_file_attachment) { + buttonId = BUTTON_FILE_ATTACHMENT; + } else if (id == R.id.action_pdf_layers) { + buttonId = BUTTON_VIEW_LAYERS; + } else if (id == R.id.action_digital_signatures) { + buttonId = BUTTON_DIGITAL_SIGNATURE; + } else if (id == R.id.action_close_tab) { + buttonId = BUTTON_CLOSE; + } + + return buttonId; + } + @Nullable private ToolbarButtonType convStringToToolbarType(String item) { ToolbarButtonType buttonType = null; @@ -2161,6 +2206,16 @@ public boolean onToolbarOptionsItemSelected(MenuItem item) { params.putString(TOOLBAR_ITEM_KEY_ID, itemKey); onReceiveNativeEvent(params); return true; + } else { + itemKey = convItemIdToString(itemId); + // check if the item's behavior should be overridden + if (itemKey != null && mToolbarOverrideButtons != null && mToolbarOverrideButtons.contains(itemKey)) { + WritableMap params = Arguments.createMap(); + params.putString(ON_TOOLBAR_BUTTON_PRESS, ON_TOOLBAR_BUTTON_PRESS); + params.putString(TOOLBAR_ITEM_KEY_ID, itemKey); + onReceiveNativeEvent(params); + return true; + } } return super.onToolbarOptionsItemSelected(item); diff --git a/ios/DocumentViewController/RNTPTDocumentViewController.h b/ios/DocumentViewController/RNTPTDocumentViewController.h index cca354d14..51df7dca6 100644 --- a/ios/DocumentViewController/RNTPTDocumentViewController.h +++ b/ios/DocumentViewController/RNTPTDocumentViewController.h @@ -43,6 +43,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)rnt_documentViewControllerDidRotatePages:(PTDocumentBaseViewController *)documentViewController forPageNumbers:(NSIndexSet *)pageNumbers; +- (void)rnt_documentViewControllerToolbarButtonPressed:(PTDocumentBaseViewController *)documentViewController buttonString:(NSString *)buttonString; + @end @class RNTPTDocumentViewController; diff --git a/ios/RNTPTDocumentView.h b/ios/RNTPTDocumentView.h index 8bd853b46..6a4a34032 100644 --- a/ios/RNTPTDocumentView.h +++ b/ios/RNTPTDocumentView.h @@ -379,6 +379,8 @@ static NSString * const PTSignaturesManager_signatureDirectory = @"PTSignaturesM - (void)annotationToolbarItemPressed:(RNTPTDocumentView *)sender withKey:(NSString *)itemKey; +- (void)toolbarButtonPressed:(RNTPTDocumentView *)sender withKey:(NSString *)itemKey; + @end @interface RNTPTDocumentView : UIView @@ -528,6 +530,8 @@ static NSString * const PTSignaturesManager_signatureDirectory = @"PTSignaturesM @property (nonatomic, copy, nullable) NSString *defaultEraserType; +@property (nonatomic, copy, nullable) NSArray *overrideToolbarButtonBehavior; + #pragma mark - Methods - (void)setToolMode:(NSString *)toolMode; diff --git a/ios/RNTPTDocumentView.m b/ios/RNTPTDocumentView.m index 235c78b1d..add740a3b 100644 --- a/ios/RNTPTDocumentView.m +++ b/ios/RNTPTDocumentView.m @@ -2547,6 +2547,38 @@ - (void)applyDocumentControllerSettings:(PTDocumentController *)documentControll } documentController.toolbarItems = [bottomToolbarItems copy]; } + + // Override action of overridden toolbar button items + if (self.overrideToolbarButtonBehavior) { + for (NSString *buttonString in self.overrideToolbarButtonBehavior) { + UIBarButtonItem *toolbarItem = [self itemForButton:buttonString + inViewController:documentController]; + + NSString *actionName = [NSString stringWithFormat:@"overriddenPressed_%@", + buttonString]; + const SEL selector = NSSelectorFromString(actionName); + + RNTPT_addMethod([documentController class], selector, ^(id documentController) { + if ([documentController isKindOfClass:[RNTPTDocumentController class]]) { + RNTPTDocumentController *controller = documentController; + + if ([controller.delegate respondsToSelector:@selector(rnt_documentViewControllerToolbarButtonPressed:buttonString:)]) { + [controller.delegate rnt_documentViewControllerToolbarButtonPressed:controller + buttonString:buttonString]; + } + } else if ([documentController isKindOfClass:[RNTPTCollaborationDocumentController class]]) { + RNTPTCollaborationDocumentController *controller = documentController; + + if ([controller.delegate respondsToSelector:@selector(rnt_documentViewControllerToolbarButtonPressed:buttonString:)]) { + [controller.delegate rnt_documentViewControllerToolbarButtonPressed:controller + buttonString:buttonString]; + } + } + }); + + toolbarItem.action = selector; + } + } } - (PTToolGroup *)toolGroupForKey:(PTDefaultAnnotationToolbarKey)key toolGroupManager:(PTToolGroupManager *)toolGroupManager @@ -3507,6 +3539,14 @@ - (void)rnt_documentViewControllerSavedSignaturesChanged:(PTDocumentBaseViewCont } } +- (void)rnt_documentViewControllerToolbarButtonPressed:(PTDocumentBaseViewController *)documentViewController + buttonString:(NSString *)buttonString +{ + if ([self.delegate respondsToSelector:@selector(toolbarButtonPressed:withKey:)]) { + [self.delegate toolbarButtonPressed:self withKey:buttonString]; + } +} + - (NSDictionary *)getAnnotationData:(PTAnnot *)annot pageNumber:(int)pageNumber pdfViewCtrl:(PTPDFViewCtrl *)pdfViewCtrl { if (![annot IsValid]) { return nil; diff --git a/ios/RNTPTDocumentViewManager.m b/ios/RNTPTDocumentViewManager.m index 48e13fdca..35b7e8172 100644 --- a/ios/RNTPTDocumentViewManager.m +++ b/ios/RNTPTDocumentViewManager.m @@ -644,6 +644,13 @@ - (instancetype)init } } +RCT_CUSTOM_VIEW_PROPERTY(overrideToolbarButtonBehavior, NSArray, RNTPTDocumentView) +{ + if (json) { + view.overrideToolbarButtonBehavior = [RCTConvert NSArray:json]; + } +} + - (UIView *)view { @@ -960,6 +967,16 @@ - (void)annotationToolbarItemPressed:(RNTPTDocumentView *)sender withKey:(NSStri } } +- (void)toolbarButtonPressed:(RNTPTDocumentView *)sender withKey:(NSString *)itemKey +{ + if (sender.onChange) { + sender.onChange(@{ + @"onToolbarButtonPress": @"onToolbarButtonPress", + PTAnnotationToolbarItemKeyId: (itemKey ?: @"") + }); + } +} + #pragma mark - Methods - (void)setToolModeForDocumentViewTag:(NSNumber *)tag toolMode:(NSString *)toolMode diff --git a/lib/src/DocumentView/DocumentView.js b/lib/src/DocumentView/DocumentView.js index ef4084e6c..2df52a2c5 100644 --- a/lib/src/DocumentView/DocumentView.js +++ b/lib/src/DocumentView/DocumentView.js @@ -151,6 +151,8 @@ const propTypes = { rememberLastUsedTool: PropTypes.bool, overflowMenuButtonIcon: PropTypes.string, maxSignatureCount: PropTypes.number, + overrideToolbarButtonBehavior: arrayOf(Config.Buttons), + onToolbarButtonPress: func(), ...ViewPropTypes, }; /** @@ -416,6 +418,13 @@ export class DocumentView extends PureComponent { }); } } + else if (event.nativeEvent.onToolbarButtonPress) { + if (this.props.onToolbarButtonPress) { + this.props.onToolbarButtonPress({ + 'id': event.nativeEvent.id, + }); + } + } }; // Methods getDocumentPath = () => { diff --git a/package.json b/package.json index 27b25470c..2a83cd61d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-pdftron", "title": "React Native Pdftron", - "version": "3.0.2-beta.111", + "version": "3.0.2-beta.112", "description": "React Native Pdftron", "main": "./lib/index.js", "typings": "index.ts", diff --git a/src/DocumentView/DocumentView.tsx b/src/DocumentView/DocumentView.tsx index fe372db3c..558571110 100644 --- a/src/DocumentView/DocumentView.tsx +++ b/src/DocumentView/DocumentView.tsx @@ -160,6 +160,8 @@ const propTypes = { rememberLastUsedTool: PropTypes.bool, overflowMenuButtonIcon: PropTypes.string, maxSignatureCount: PropTypes.number, + overrideToolbarButtonBehavior: arrayOf(Config.Buttons), + onToolbarButtonPress: func<(event: {id: string}) => void>(), ...ViewPropTypes, }; @@ -412,6 +414,12 @@ export class DocumentView extends PureComponent { 'currentTab': event.nativeEvent.currentTab }); } + } else if (event.nativeEvent.onToolbarButtonPress) { + if (this.props.onToolbarButtonPress) { + this.props.onToolbarButtonPress({ + 'id': event.nativeEvent.id, + }); + } } }