Skip to content
DemoSampleAPI ReferenceFAQ

PDF Generation Template Editor

Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.

View on GitHub
Android Guides Context menu

Context Menu ​

When an annotation, text, form, or content editor object is selected, a context menu pops up to support object operations. ContextMenuConfig controls the menu style and the menu item list for each scenario.

Global Style ​

json
{
  "contextMenuConfig": {
    "backgroundColor": "",
    "fontSize": 14,
    "padding": [0, 0, 0, 0],
    "iconSize": 36
  }
}
FieldDescription
backgroundColorMenu background color (empty string uses default)
fontSizeMenu text size
paddingMenu padding [left, top, right, bottom]
iconSizeIcon size

The global configuration applies to global context menus across all modes:

json
{
  "contextMenuConfig": {
    "global": {
      "screenshot": [
        { "key": "exit" },
        { "key": "share" }
      ]
    }
  }
}

Viewer Mode Menu ​

viewMode configures menus in viewer mode:

json
{
  "contextMenuConfig": {
    "viewMode": {
      "textSelect": [
        { "key": "copy" }
      ]
    }
  }
}

Annotation Mode Menu ​

annotationMode contains the following sub-menu scenarios:

Text Selection ​

json
"textSelect": [
  { "key": "copy" },
  { "key": "highlight" },
  { "key": "underline" },
  { "key": "strikeout" },
  { "key": "squiggly" }
]

Long Press on Blank Area ​

json
"longPressContent": [
  { "key": "paste" },
  { "key": "note" },
  { "key": "textBox" },
  { "key": "stamp" },
  { "key": "image" }
]

Markup Annotations (Highlight/Underline/Strikeout/Squiggly) ​

json
"markupContent": [
  { "key": "properties" },
  { "key": "note" },
  { "key": "reply" },
  { "key": "viewReply" },
  { "key": "delete" }
]

Other Annotation Types ​

ScenarioConfig KeySupported Menu Items
InkinkContentproperties, note, reply, viewReply, delete
ShapeshapeContentproperties, note, reply, viewReply, delete
FreeTextfreeTextContentproperties, edit, reply, viewReply, delete
SoundsoundContentreply, viewReply, play, record, delete
StampstampContentnote, reply, viewReply, delete, rotate
Signature StampsignStampContentsignHere, delete, rotate
LinklinkContentedit, delete

Content Editor Mode Menu ​

contentEditorMode contains the following scenarios:

Text Area ​

json
"editTextAreaContent": [
  { "key": "properties" },
  { "key": "edit" },
  { "key": "cut" },
  { "key": "copy" },
  { "key": "delete" }
]

Selected Text ​

json
"editSelectTextContent": [
  { "key": "properties" },
  { "key": "opacity", "subItems": ["25%", "50%", "75%", "100%"] },
  { "key": "cut" },
  { "key": "copy" },
  { "key": "delete" }
]

Text Input ​

json
"editTextContent": [
  { "key": "select" },
  { "key": "selectAll" },
  { "key": "paste" }
]

Image Area ​

json
"imageAreaContent": [
  { "key": "properties" },
  { "key": "rotateLeft" },
  { "key": "rotateRight" },
  { "key": "replace" },
  { "key": "export" },
  { "key": "opacity", "subItems": ["25%", "50%", "75%", "100%"] },
  { "key": "flipHorizontal" },
  { "key": "flipVertical" },
  { "key": "crop" },
  { "key": "delete" },
  { "key": "copy" },
  { "key": "cut" }
]

Path Area ​

json
"editPathContent": [
  { "key": "delete" }
]

Long Press on Blank Area ​

json
"longPressWithEditTextMode": [
  { "key": "addText" },
  { "key": "paste" },
  { "key": "keepSourceFormatingPaste" }
]
json
"longPressWithEditImageMode": [
  { "key": "addImages" },
  { "key": "paste" }
]

Search & Replace ​

json
"searchReplace": [
  { "key": "replace" }
]

Form Mode Menu ​

formMode configures menus for each form type:

json
{
  "contextMenuConfig": {
    "formMode": {
      "textField":      [{ "key": "properties" }, { "key": "delete" }],
      "checkBox":       [{ "key": "properties" }, { "key": "delete" }],
      "radioButton":    [{ "key": "properties" }, { "key": "delete" }],
      "listBox":        [{ "key": "options" }, { "key": "properties" }, { "key": "delete" }],
      "comboBox":       [{ "key": "options" }, { "key": "properties" }, { "key": "delete" }],
      "signatureField": [{ "key": "startToSign" }, { "key": "delete" }],
      "pushButton":     [{ "key": "options" }, { "key": "properties" }, { "key": "delete" }]
    }
  }
}

Adding Custom Menu Items ​

Add custom buttons to any menu scenario:

1. JSON Configuration ​

json
{
  "contextMenuConfig": {
    "annotationMode": {
      "markupContent": [
        { "key": "properties" },
        { "key": "note" },
        {
          "key": "custom",
          "identifier": "custom_markup_action_get_text",
          "title": "Get Text",
          "icon": "ic_test_get_text",
          "showType": "text"
        },
        { "key": "delete" }
      ]
    }
  }
}
FieldDescription
keyMust be "custom" for custom buttons
identifierUnique identifier to distinguish different buttons in callbacks
titleDisplay text
iconIcon resource name (must be in res/drawable)
showTypeDisplay type: "text" or "icon"

2. Adding Callbacks ​

java
CPDFCustomEventCallbackHelper.getInstance().addCustomEventCallback(extraMap -> {
    String customEventType = extraMap.get(
        CPDFCustomEventField.CUSTOM_EVENT_TYPE).toString();
    if (CPDFCustomEventType.CONTEXT_MENU_ITEM_TAPPED.equals(customEventType)) {
        String identifier = extraMap.get(CPDFCustomEventField.IDENTIFIER).toString();
        switch (identifier) {
            case "custom_markup_action_get_text":
                CPDFAnnotation annotation = (CPDFAnnotation) extraMap.get(
                    CPDFCustomEventField.ANNOTATION);
                if (annotation instanceof CPDFMarkupAnnotation) {
                    String text = ((CPDFMarkupAnnotation) annotation).getMarkedText();
                    CToastUtil.showToast(getApplicationContext(), text);
                }
                break;
        }
    }
});
kotlin
CPDFCustomEventCallbackHelper.getInstance().addCustomEventCallback { extraMap ->
    val customEventType = extraMap[CPDFCustomEventField.CUSTOM_EVENT_TYPE].toString()
    if (CPDFCustomEventType.CONTEXT_MENU_ITEM_TAPPED == customEventType) {
        val identifier = extraMap[CPDFCustomEventField.IDENTIFIER].toString()
        when (identifier) {
            "custom_markup_action_get_text" -> {
                val annotation = extraMap[CPDFCustomEventField.ANNOTATION]
                if (annotation is CPDFMarkupAnnotation) {
                    CToastUtil.showToast(applicationContext, annotation.markedText)
                }
            }
        }
    }
}

Preview ​

Custom context menu preview