Skip to content
ComPDF
Guides

Custom Menu

When viewing a PDF, if a user selects text or long-presses on a blank area, the PDF enters the corresponding interaction state. At this point, the system will display a context menu to perform operations related to the current interaction.

By inheriting CPDFContextMenuShowHelper and overriding the appropriate methods, you can customize the menu layout, content, and interaction behavior. For example, the context menu for a highlight annotation can include actions such as “Modify Properties,” “Copy Text,” and “Delete Annotation.”

Operation Flow Diagram

tex
User Action

   │ Select text / Long-press blank area

PDF enters corresponding interaction state

   │ Context menu appears

Custom menu item clicked

   │ Execute corresponding operation (modify properties / copy text / delete annotation, etc.)

Refresh PDF page / update UI

Example Diagram (Highlight Annotation):

tsx
+---------------------+
|  Highlight          |
|  Lorem ipsum...     |
+---------------------+

        ▼  Long-press / Click menu
+---------------------+
| Properties | Copy | Delete |   <- Custom Context Menu
+---------------------+

Example: Custom Menu for Highlight Annotations

t_markup_annot_menu_layout.xml:

xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_context_menu_window"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/attr"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Properties" />

    <TextView
        android:id="@+id/copy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Copy" />

    <TextView
        android:id="@+id/delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Delete" />

</LinearLayout>
java
public class TContextMenuHelper extends CPDFContextMenuShowHelper {
    @Override
    public View getMarkupContentView(CPDFPageView pageView, CPDFBaseAnnotImpl annotImpl, LayoutInflater layoutInflater) {
        View contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null);
        CPDFMarkupAnnotImpl markupAnnotImpl = (CPDFMarkupAnnotImpl) annotImpl;
        CPDFMarkupAnnotation markupAnnotation = markupAnnotImpl.onGetAnnotation();

        // Set menu click actions
        invokeOnClickListener(contentView, v -> {
            int id = v.getId();
            if (id == R.id.attr) {  // Modify properties
                markupAnnotation.setColor(Color.RED);
                markupAnnotation.setAlpha(100);
                markupAnnotation.updateAp();
                markupAnnotImpl.onAnnotAttrChange();
                pageView.invalidate();
            } else if (id == R.id.copy) { // Copy text
                String markedText = markupAnnotation.getMarkedText();
                if (!TextUtils.isEmpty(markedText)) {
                    CPDFTextUtils.setClipData(context, "ComPDF", markedText);
                }
            } else if (id == R.id.delete) { // Delete annotation
                pageView.deleteAnnotation(annotImpl);
            }
            popupWindow.dismiss();
        }, R.id.attr, R.id.copy, R.id.delete);

        return contentView;
    }
}
kotlin
class TContextMenuHelper(readerView: CPDFReaderView?) : CPDFContextMenuShowHelper(readerView) {
    override fun getMarkupContentView(
        pageView: CPDFPageView,
        annotImpl: CPDFBaseAnnotImpl<*>,
        layoutInflater: LayoutInflater
    ): View {
        val contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null)
        val markupAnnotImpl = annotImpl as CPDFMarkupAnnotImpl
        val markupAnnotation = markupAnnotImpl.onGetAnnotation()

        // Set menu click actions
        invokeOnClickListener(contentView, { v ->
            when (v.id) {
                R.id.attr -> { // Modify properties
                    markupAnnotation.color = Color.RED
                    markupAnnotation.alpha = 100
                    markupAnnotation.updateAp()
                    markupAnnotImpl.onAnnotAttrChange()
                    pageView.invalidate()
                }
                R.id.copy -> { // Copy text
                    val markedText = markupAnnotation.markedText
                    if (markedText.isNotEmpty()) {
                        CPDFTextUtils.setClipData(context, "ComPDF", markedText)
                    }
                }
                R.id.delete -> { // Delete annotation
                    pageView.deleteAnnotation(annotImpl)
                }
            }
            popupWindow.dismiss()
        }, R.id.attr, R.id.copy, R.id.delete)

        return contentView
    }
}

Set CPDFReaderView to use the custom context menu:

java
getCPdfReaderView().setContextMenuShowListener(new TContextMenuHelper(readerView));

List of Methods for Custom Context Menus

MethodApplicable Annotation/OperationDescription
getShapeContentViewShape annotationsCustom context menu for shapes
getFreetextContentViewFreeText annotationsCustom context menu for FreeText
getMarkupContentViewHighlight / Underline / SquigglyCustom menu for markup annotations
getInkContentViewInk / Signature annotationsCustom menu for ink annotations
getStampContentViewStamp annotationsCustom menu for stamp annotations
getLinkContentViewLink annotationsCustom menu for link annotations
getNoteContentViewNote / CommentCustom menu for note annotations
getSoundContentViewAudio annotationsCustom menu for audio annotations
getCheckboxContentViewForm - CheckboxCustom menu for checkbox forms
getComboboxContentViewForm - ComboBoxCustom menu for dropdown forms
getListboxContentViewForm - ListBoxCustom menu for list box forms
getPushbuttonContentViewForm - ButtonCustom menu for button forms
getRadiobuttonContentViewForm - RadioButtonCustom menu for radio buttons
getSignatureContentViewDigital SignatureCustom menu for signature fields
getTextfieldContentViewForm - TextFieldCustom menu for text fields
getSelectTextContentViewText selectionCustom menu for selected text
getEditImageAreaContentViewImage editing areaCustom menu for image editing
getLongPressContentViewLong-press on blank areaMenu for blank area long-press
getEditLongPressContentViewLong-press in edit modeMenu for edit mode long-press
getEditTextAreaContentViewText area editingMenu for text editing area
getEditSelectTextContentViewEdit mode selected textMenu for selected text in edit mode
getEditTextContentViewEdit textMenu for editing text
getRedactContentViewRedact / Hide contentMenu for redaction actions
getCropImageAreaContentViewImage croppingMenu for image cropping
getSearchReplaceContentViewSearch / ReplaceMenu for search & replace
getEditPathAreaContentViewPath editingMenu for path editing
getScreenShotContentViewScreenshot areaMenu for screenshot actions

Note: All methods in the table can be overridden by inheriting CPDFContextMenuShowHelper to implement custom menus. Each method corresponds to a specific annotation type or operation type, allowing developers to customize menu layout and behavior as needed.