Skip to content

Commit

Permalink
Merge pull request #345 from PSPDFKit/reinhard/344-additional-configu…
Browse files Browse the repository at this point in the history
…ration

Add more Android configuration options
  • Loading branch information
Reinhard Hafenscher authored Feb 4, 2020
2 parents 3ab0daa + b90d3d7 commit 6841c48
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 67 deletions.
22 changes: 20 additions & 2 deletions android/src/main/java/com/pspdfkit/react/ConfigurationAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
import com.pspdfkit.configuration.page.PageScrollMode;
import com.pspdfkit.configuration.sharing.ShareFeatures;

import java.util.EnumSet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -84,6 +82,8 @@ public class ConfigurationAdapter {
private static final String AUTOSAVE_DISABLED = "disableAutomaticSaving";
private static final String ANNOTATION_EDITING_ENABLED = "enableAnnotationEditing";
private static final String EDITABLE_ANNOTATION_TYPES = "editableAnnotationTypes";
private static final String SHOW_SETTINGS_MENU = "showSettingsMenu";
private static final String TOOLBAR_TITLE = "toolbarTitle";

private final PdfActivityConfiguration.Builder configuration;

Expand Down Expand Up @@ -174,6 +174,12 @@ public ConfigurationAdapter(@NonNull Context context, ReadableMap configuration)
if (configuration.hasKey(EDITABLE_ANNOTATION_TYPES)) {
configureEditableAnnotationTypes(configuration.getArray(EDITABLE_ANNOTATION_TYPES));
}
if (configuration.hasKey(SHOW_SETTINGS_MENU)) {
configureSettingsMenuShown(configuration.getBoolean(SHOW_SETTINGS_MENU));
}
if (configuration.hasKey(TOOLBAR_TITLE)) {
configureToolbarTitle(configuration.getString(TOOLBAR_TITLE));
}
}
}

Expand Down Expand Up @@ -396,6 +402,18 @@ private void configureEditableAnnotationTypes(@Nullable final ReadableArray edit
configuration.editableAnnotationTypes(parsedTypes);
}

private void configureSettingsMenuShown(final boolean settingsMenuShown) {
if (settingsMenuShown) {
configuration.showSettingsMenu();
} else {
configuration.hideSettingsMenu();
}
}

private void configureToolbarTitle(@Nullable final String customTitle) {
configuration.title(customTitle);
}

public PdfActivityConfiguration build() {
return configuration.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ public void setMenuItemGrouping(PdfView view, @NonNull ReadableArray menuItemGro
view.setMenuItemGroupingRule(groupingRule);
}

@ReactProp(name = "showNavigationButtonInToolbar")
public void setShowNavigationButtonInToolbar(@NonNull final PdfView view, final boolean showNavigationButtonInToolbar) {
view.setShowNavigationButtonInToolbar(showNavigationButtonInToolbar);
}

@Nullable
@Override
public Map getExportedCustomDirectEventTypeConstants() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.pspdfkit.react.events;

import androidx.annotation.IdRes;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;

/**
* Event sent by the {@link com.pspdfkit.views.PdfView} when navigation button was clicked.
*/
public class PdfViewNavigationButtonClickedEvent extends Event<PdfViewNavigationButtonClickedEvent> {

public static final String EVENT_NAME = "pdfViewNavgigationButtonClicked";

public PdfViewNavigationButtonClickedEvent(@IdRes int viewId) {
super(viewId);
}

@Override
public String getEventName() {
return EVENT_NAME;
}

@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
WritableMap eventData = Arguments.createMap();
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData);
}
}

This file was deleted.

67 changes: 47 additions & 20 deletions android/src/main/java/com/pspdfkit/views/PdfView.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
import com.pspdfkit.react.events.PdfViewDocumentLoadFailedEvent;
import com.pspdfkit.react.events.PdfViewDocumentSaveFailedEvent;
import com.pspdfkit.react.events.PdfViewDocumentSavedEvent;
import com.pspdfkit.react.events.PdfViewNavigationButtonClickedEvent;
import com.pspdfkit.react.events.PdfViewStateChangedEvent;
import com.pspdfkit.react.helper.DocumentJsonDataProvider;
import com.pspdfkit.ui.DocumentDescriptor;
import com.pspdfkit.ui.PdfFragment;
import com.pspdfkit.ui.PdfUi;
import com.pspdfkit.ui.PdfUiFragment;
import com.pspdfkit.ui.PdfUiFragmentBuilder;
import com.pspdfkit.ui.toolbar.grouping.MenuItemGroupingRule;
Expand All @@ -50,6 +50,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -97,7 +98,10 @@ public class PdfView extends FrameLayout {

@Nullable
private PdfUiFragment fragment;
private BehaviorSubject<PdfUiFragment> pdfUiFragmentGetter = BehaviorSubject.create();

/** We wrap the fragment in a list so we can have a state that encapsulates no element being set. */
@NonNull
private final BehaviorSubject<List<PdfUiFragment>> pdfUiFragmentGetter = BehaviorSubject.createDefault(Collections.emptyList());

/** An internal id we generate so we can track if fragments found belong to this specific PdfView instance. */
private int internalId;
Expand Down Expand Up @@ -219,6 +223,14 @@ public void setMenuItemGroupingRule(@NonNull MenuItemGroupingRule groupingRule)
pdfViewModeController.setMenuItemGroupingRule(groupingRule);
}

public void setShowNavigationButtonInToolbar(final boolean showNavigationButtonInToolbar) {
pendingFragmentActions.add(getCurrentPdfUiFragment()
.observeOn(Schedulers.io())
.subscribe(pdfUiFragment -> {
((ReactPdfUiFragment) pdfUiFragment).setShowNavigationButtonInToolbar(showNavigationButtonInToolbar);
}));
}

private void setupFragment() {
if (fragmentTag != null && configuration != null && document != null) {
PdfUiFragment pdfFragment = (PdfUiFragment) fragmentManager.findFragmentByTag(fragmentTag);
Expand All @@ -235,7 +247,7 @@ private void setupFragment() {
if (pdfFragment == null) {
pdfFragment = PdfUiFragmentBuilder.fromDocumentDescriptor(getContext(), DocumentDescriptor.fromDocument(document))
.configuration(configuration)
.fragmentClass(ConfigurationChangeReportingPdfUiFragment.class)
.fragmentClass(ReactPdfUiFragment.class)
.build();
// We put our internal id so we can track if this fragment belongs to us, used to handle orphaned fragments after hot reloads.
pdfFragment.getArguments().putInt(ARG_ROOT_ID, internalId);
Expand All @@ -249,7 +261,7 @@ private void setupFragment() {
// The document changed create a new PdfFragment.
pdfFragment = PdfUiFragmentBuilder.fromDocumentDescriptor(getContext(), DocumentDescriptor.fromDocument(document))
.configuration(configuration)
.fragmentClass(ConfigurationChangeReportingPdfUiFragment.class)
.fragmentClass(ReactPdfUiFragment.class)
.build();
prepareFragment(pdfFragment);
} else if (fragmentView != null && fragmentView.getParent() != this) {
Expand All @@ -266,7 +278,7 @@ private void setupFragment() {
}

fragment = pdfFragment;
pdfUiFragmentGetter.onNext(fragment);
pdfUiFragmentGetter.onNext(Collections.singletonList(pdfFragment));
}
}

Expand All @@ -279,9 +291,17 @@ private void prepareFragment(final PdfUiFragment pdfUiFragment) {

pdfUiFragment.setOnContextualToolbarLifecycleListener(pdfViewModeController);
pdfUiFragment.getPSPDFKitViews().getFormEditingBarView().addOnFormEditingBarLifecycleListener(pdfViewModeController);
((ConfigurationChangeReportingPdfUiFragment) pdfUiFragment).setOnConfigurationChangedListener(() -> {
// If the configuration was changed from the UI a new fragment will be created, reattach our listeners.
preparePdfFragment(pdfUiFragment.getPdfFragment());
((ReactPdfUiFragment) pdfUiFragment).setReactPdfUiFragmentListener(new ReactPdfUiFragment.ReactPdfUiFragmentListener() {
@Override
public void onConfigurationChanged(@NonNull PdfUiFragment pdfUiFragment) {
// If the configuration was changed from the UI a new fragment will be created, reattach our listeners.
preparePdfFragment(pdfUiFragment.getPdfFragment());
}

@Override
public void onNavigationButtonClicked(@NonNull PdfUiFragment pdfUiFragment) {
eventDispatcher.dispatchEvent(new PdfViewNavigationButtonClickedEvent(getId()));
}
});

// After attaching the PdfUiFragment we can access the PdfFragment.
Expand Down Expand Up @@ -315,14 +335,14 @@ public void removeFragment(boolean makeInactive) {
// Clear everything.
isActive = false;
document = null;

pendingFragmentActions.dispose();
pendingFragmentActions = new CompositeDisposable();
}

fragment = null;

pdfUiFragmentGetter.onComplete();
pdfUiFragmentGetter = BehaviorSubject.create();
pendingFragmentActions.dispose();
pendingFragmentActions = new CompositeDisposable();
pdfUiFragmentGetter.onNext(Collections.emptyList());
}

void manuallyLayoutChildren() {
Expand Down Expand Up @@ -622,9 +642,15 @@ public Maybe<Boolean> setFormFieldValue(@NonNull String formElementName, @NonNul

/** Returns the {@link PdfFragment} hosted in the current {@link PdfUiFragment}. */
private Observable<PdfFragment> getCurrentPdfFragment() {
return getPdfFragment()
.take(1);
}

/** Returns the {@link PdfUiFragment}. */
private Observable<PdfUiFragment> getCurrentPdfUiFragment() {
return pdfUiFragmentGetter
.filter(pdfUiFragment -> pdfUiFragment.getPdfFragment() != null)
.map(PdfUiFragment::getPdfFragment)
.filter(pdfUiFragments -> !pdfUiFragments.isEmpty())
.map(pdfUiFragments -> pdfUiFragments.get(0))
.take(1);
}

Expand All @@ -642,24 +668,25 @@ public Maybe<PdfFragment> getActivePdfFragment() {
*/
public Observable<PdfFragment> getPdfFragment() {
return pdfUiFragmentGetter
.filter(pdfUiFragments -> !pdfUiFragments.isEmpty())
.map(pdfUiFragments -> pdfUiFragments.get(0))
.filter(pdfUiFragment -> pdfUiFragment.getPdfFragment() != null)
.map(PdfUiFragment::getPdfFragment);
}

/** Returns the current fragment if it is set. */
public Maybe<PdfFragment> getFragment() {
return pdfUiFragmentGetter.firstElement().map(PdfUi::getPdfFragment);
}

/** Returns the event registration map for the default events emitted by the {@link PdfView}. */
public static Map<String, Map<String, String>> createDefaultEventRegistrationMap() {
return MapBuilder.of(PdfViewStateChangedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onStateChanged"),
Map<String , Map<String, String>> map = MapBuilder.of(PdfViewStateChangedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onStateChanged"),
PdfViewDocumentSavedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDocumentSaved"),
PdfViewAnnotationTappedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onAnnotationTapped"),
PdfViewAnnotationChangedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onAnnotationsChanged"),
PdfViewDataReturnedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDataReturned"),
PdfViewDocumentSaveFailedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDocumentSaveFailed"),
PdfViewDocumentLoadFailedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDocumentLoadFailed")
);

map.put(PdfViewNavigationButtonClickedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onNavigationButtonClicked"));

return map;
}
}
67 changes: 67 additions & 0 deletions android/src/main/java/com/pspdfkit/views/ReactPdfUiFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.pspdfkit.views;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;

import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
import com.pspdfkit.react.R;
import com.pspdfkit.ui.PdfUiFragment;

/**
* This {@link PdfUiFragment} provides additional callbacks to improve integration into react native.
* <p/>
* <ul>
* <li>A callback when the configuration was changed.</li>
* <li>A method to show and hide the navigation button in the toolbar, as well as a callback for when it is clicked.</li>
* </ul>
*/
public class ReactPdfUiFragment extends PdfUiFragment {

@Nullable private ReactPdfUiFragmentListener reactPdfUiFragmentListener;

void setReactPdfUiFragmentListener(@Nullable ReactPdfUiFragmentListener listener) {
this.reactPdfUiFragmentListener = listener;
}

@Override
public void performApplyConfiguration(@NonNull PdfActivityConfiguration configuration) {
super.performApplyConfiguration(configuration);

if (this.reactPdfUiFragmentListener != null) {
reactPdfUiFragmentListener.onConfigurationChanged(this);
}
}


/** When set to true will add a navigation arrow to the toolbar. */
void setShowNavigationButtonInToolbar(final boolean showNavigationButtonInToolbar) {
if (getView() == null) {
return;
}
Toolbar toolbar = getView().findViewById(R.id.pspdf__toolbar_main);
if (showNavigationButtonInToolbar) {
toolbar.setNavigationIcon(R.drawable.pspdf__ic_navigation_arrow);
toolbar.setNavigationOnClickListener(v -> {
if (reactPdfUiFragmentListener != null) {
reactPdfUiFragmentListener.onNavigationButtonClicked(this);
}
});
} else {
toolbar.setNavigationIcon(null);
toolbar.setNavigationOnClickListener(null);
}
}

/**
* Listener that notifies of actions taken directly in the PdfUiFragment.
*/
public interface ReactPdfUiFragmentListener {

/** Called when the configuration changed, reset your {@link com.pspdfkit.ui.PdfFragment} listeners in here. */
void onConfigurationChanged(@NonNull PdfUiFragment pdfUiFragment);

/** Called when the back navigation button was clicked. */
void onNavigationButtonClicked(@NonNull PdfUiFragment pdfUiFragment);
}
}
9 changes: 9 additions & 0 deletions android/src/main/res/drawable/pspdf__ic_navigation_arrow.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
Loading

0 comments on commit 6841c48

Please sign in to comment.