Skip to content
ComPDF
Guides

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