Reference Source
public class | source

ContextMenu

A customizable HTML context menu.

Overview

  • Attach to anything that fires a contextmenu event
  • Configure custom items
  • Allows to dynamically enable or disable items
  • Configure custom style with custom CSS (see examples above)

Usage

In the example below we'll create a ContextMenu that pops up whenever we right-click on an Entity within our Scene.

First, we'll create the ContextMenu, configuring it with a list of menu items.

Each item has:

  • a title to display it in the menu,
  • a doAction() callback to fire when the item's title is clicked, and
  • an optional getEnabled() callback that indicates if the item should enabled in the menu or not.

The getEnabled() callbacks are invoked whenever the menu is shown. When an item's getEnabled() callback returns true, then the item is enabled and clickable. When it returns false, then the item is disabled and cannot be clicked. An item without a getEnabled() callback is always enabled and clickable.

Note how the doAction() and getEnabled() callbacks accept a context object. That must be set on the ContextMenu before we're able to we show it. The context object can be anything. In this example, we'll use the context object to provide the callbacks with the Entity that we right-clicked.

We'll also initially enable the ContextMenu.

[Run this example]

const canvasContextMenu = new ContextMenu({

   enabled: true,

   items: [
      [
         {
            title: "Hide Object",
            getEnabled: (context) => {
                return context.entity.visible; // Can't hide entity if already hidden
            },
            doAction: function (context) {
                context.entity.visible = false;
            }
         }
      ],
      [
         {
            title: "Select Object",
            getEnabled: (context) => {
                return (!context.entity.selected); // Can't select an entity that's already selected
            },
            doAction: function (context) {
                context.entity.selected = true;
            }
         }
      ],
      [
         {
            title: "X-Ray Object",
            getEnabled: (context) => {
                return (!context.entity.xrayed); // Can't X-ray an entity that's already X-rayed
            },
            doAction: (context) => {
                context.entity.xrayed = true;
            }
         }
      ]
   ]
});

Next, we'll make the ContextMenu appear whenever we right-click on an Entity. Whenever we right-click on the canvas, we'll attempt to pick the Entity at those mouse coordinates. If we succeed, we'll feed the Entity into ContextMenu via the context object, then show the ContextMenu.

From there, each ContextMenu item's getEnabled() callback will be invoked (if provided), to determine if the item should be enabled. If we click an item, its doAction() callback will be invoked with our context object.

Remember that we must set the context on our ContextMenu before we show it, otherwise it will log an error to the console, and ignore our attempt to show it.

viewer.scene.canvas.canvas.oncontextmenu = (e) => { // Right-clicked on the canvas

    if (!objectContextMenu.enabled) {
        return;
    }

    var hit = viewer.scene.pick({ // Try to pick an Entity at the coordinates
        canvasPos: [e.pageX, e.pageY]
    });

    if (hit) { // Picked an Entity

        objectContextMenu.context = { // Feed entity to ContextMenu
            entity: hit.entity
        };

        objectContextMenu.show(e.pageX, e.pageY); // Show the ContextMenu
    }

    e.preventDefault();
});

Note how we only show the ContextMenu if it's enabled. We can use that mechanism to switch between multiple ContextMenu instances depending on what we clicked.

Dynamic Item Titles

To make an item dynamically regenerate its title text whenever we show the ContextMenu, provide its title with a getTitle() callback. The callback will fire each time you show ContextMenu, which will dynamically set the item title text.

In the example below, we'll create a simple ContextMenu that allows us to toggle the selection of an object via its first item, which changes text depending on whether we are selecting or deselecting the object.

[Run an example]

const canvasContextMenu = new ContextMenu({

   enabled: true,

   items: [
      [
         {
             getTitle: (context) => {
                 return (!context.entity.selected) ? "Select" : "Undo Select";
             },
             doAction: function (context) {
                 context.entity.selected = !context.entity.selected;
             }
         },
         {
             title: "Clear Selection",
             getEnabled: function (context) {
                 return (context.viewer.scene.numSelectedObjects > 0);
             },
             doAction: function (context) {
                 context.viewer.scene.setObjectsSelected(context.viewer.scene.selectedObjectIds, false);
             }
         }
      ]
   ]
});

Constructor Summary

Public Constructor
public

Creates a context menu.

Member Summary

Public Members
public set

Sets the menu's current context.

The context can be any object that you need to be provides to the callbacks configured on ContextMenu#items.

This must be set before calling ContextMenu#show.

public get

Gets the menu's current context.

public set

Sets whether this context menu is enabled.

public get

Gets whether this context menu is enabled.

public set

Sets the context menu items.

public get

Gets the context menu items.

public get

Gets whether this context menu is currently shown or not.

Method Summary

Public Methods
public

Destroys this context menu.

public

hide()

Hides this context menu.

public

show(pageX: Number, pageY: Number)

Shows this context menu at the given page coordinates.

Public Constructors

public constructor(cfg: Object) source

Creates a context menu.

Params:

NameTypeAttributeDescription
cfg Object
  • optional

Context menu configuration.

cfg.items Object
  • optional

The context menu items. These can also be dynamically set on ContextMenu#items. See the class documentation for an example.

cfg.context Object
  • optional

The context, which is passed into the item callbacks. This can also be dynamically set on ContextMenu#context. This must be set before calling ContextMenu#show.

cfg.enabled Boolean
  • optional
  • default: true

Whether this context menu is initially enabled. ContextMenu#show does nothing while this is false.

Public Members

public set context: Object source

Sets the menu's current context.

The context can be any object that you need to be provides to the callbacks configured on ContextMenu#items.

This must be set before calling ContextMenu#show.

public get context: Object source

Gets the menu's current context.

public set enabled: Boolean source

Sets whether this context menu is enabled.

When disabling, will hide the menu if currently shown.

public get enabled: Boolean source

Gets whether this context menu is enabled.

ContextMenu#show does nothing while this is false.

public set items: Object[] source

Sets the context menu items.

These can be dynamically updated.

See class documentation for an example.

public get items: Object[] source

Gets the context menu items.

public get shown: Boolean: * source

Gets whether this context menu is currently shown or not.

Return:

Boolean

Whether this context menu is shown.

Public Methods

public destroy() source

Destroys this context menu.

public hide() source

Hides this context menu.

public show(pageX: Number, pageY: Number) source

Shows this context menu at the given page coordinates.

Also calls the getEnabled() callback on the menu items, where supplied, to enable or disable them. See the class documentation for more info.

Does nothing when ContextMenu#enabled is false.

Logs error to console and does nothing if ContextMenu#context has not been set.

Params:

NameTypeAttributeDescription
pageX Number

Page X-coordinate.

pageY Number

Page Y-coordinate.