//// entityListContextMenu.js//// exampleContextMenus.js was originally created by David Rowe on August 22nd, 2018.// Modified to entityListContextMenu.js by Thijs Wenker on October 10th, 2018// Copyright 2018 High Fidelity, Inc.// Copyright 2024 Overte e.V.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// /* eslint-env browser */const CONTEXT_MENU_CLASS = "context-menu"; /** * ContextMenu class for EntityList * @constructor */function EntityListContextMenu() { this._elContextMenu = null; this._onSelectedCallback = null; this._listItems = []; this._initialize();} EntityListContextMenu.prototype = { /** * @private */ _elContextMenu: null, /** * @private */ _onSelectedCallback: null, /** * @private */ _selectedEntityID: null, /** * @private */ _listItems: null, /** * Close the context menu */ close: function() { if (this.isContextMenuOpen()) { this._elContextMenu.style.display = "none"; } }, isContextMenuOpen: function() { return this._elContextMenu.style.display === "block"; }, /** * Open the context menu * @param clickEvent * @param selectedEntityID * @param enabledOptions */ open: function(clickEvent, selectedEntityID, enabledOptions) { this._selectedEntityID = selectedEntityID; this._listItems.forEach(function(listItem) { let enabled = enabledOptions.includes(listItem.label); listItem.enabled = enabled; listItem.element.setAttribute('class', enabled ? '' : 'disabled'); }); this._elContextMenu.style.display = "block"; this._elContextMenu.style.left = Math.min(clickEvent.pageX, document.body.offsetWidth - this._elContextMenu.offsetWidth).toString() + "px"; this._elContextMenu.style.top = Math.min(clickEvent.pageY, document.body.clientHeight - this._elContextMenu.offsetHeight).toString() + "px"; clickEvent.stopPropagation(); }, /** * Set the callback for when a menu item is selected * @param onSelectedCallback */ setOnSelectedCallback: function(onSelectedCallback) { this._onSelectedCallback = onSelectedCallback; }, /** * Add a labeled item to the context menu * @param itemLabel * @private */ _addListItem: function(itemLabel) { let elListItem = document.createElement("li"); elListItem.innerText = itemLabel; let listItem = { label: itemLabel, element: elListItem, enabled: false }; elListItem.addEventListener("click", function () { if (listItem.enabled && this._onSelectedCallback) { this._onSelectedCallback.call(this, itemLabel, this._selectedEntityID); } }.bind(this), false); elListItem.setAttribute('class', 'disabled'); this._listItems.push(listItem); this._elContextMenu.appendChild(elListItem); }, /** * Add a separator item to the context menu * @private */ _addListSeparator: function() { let elListItem = document.createElement("li"); elListItem.setAttribute('class', 'separator'); this._elContextMenu.appendChild(elListItem); }, /** * Initialize the context menu. * @private */ _initialize: function() { this._elContextMenu = document.createElement("ul"); this._elContextMenu.setAttribute("class", CONTEXT_MENU_CLASS); document.body.appendChild(this._elContextMenu); this._addListItem("Cut"); this._addListItem("Copy"); this._addListItem("Copy ID(s)"); this._addListItem("Paste"); this._addListSeparator(); this._addListItem("Rename"); this._addListItem("Duplicate"); this._addListItem("Delete"); // Ignore clicks on context menu background or separator. this._elContextMenu.addEventListener("click", function(event) { // Sink clicks on context menu background or separator but let context menu item clicks through. if (event.target.classList.contains(CONTEXT_MENU_CLASS)) { event.stopPropagation(); } }); // Provide means to close context menu without clicking menu item. document.body.addEventListener("click", this.close.bind(this)); document.body.addEventListener("keydown", function(event) { // Close context menu with Esc key. if (this.isContextMenuOpen() && event.key === "Escape") { this.close(); } }.bind(this)); }};
//
// entityListContextMenu.js
//
// exampleContextMenus.js was originally created by David Rowe on August 22nd, 2018.
// Modified to entityListContextMenu.js by Thijs Wenker on October 10th, 2018
// Copyright 2018 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/* eslint-env browser */
const CONTEXT_MENU_CLASS = "context-menu";
/**
* ContextMenu class for EntityList
* @constructor
*/
function EntityListContextMenu() {
this._elContextMenu = null;
this._onSelectedCallback = null;
this._listItems = [];
this._initialize();
}
EntityListContextMenu.prototype = {
/**
* @private
*/
_elContextMenu: null,
/**
* @private
*/
_onSelectedCallback: null,
/**
* @private
*/
_selectedEntityID: null,
/**
* @private
*/
_listItems: null,
/**
* Close the context menu
*/
close: function() {
if (this.isContextMenuOpen()) {
this._elContextMenu.style.display = "none";
}
},
isContextMenuOpen: function() {
return this._elContextMenu.style.display === "block";
},
/**
* Open the context menu
* @param clickEvent
* @param selectedEntityID
* @param enabledOptions
*/
open: function(clickEvent, selectedEntityID, enabledOptions) {
this._selectedEntityID = selectedEntityID;
this._listItems.forEach(function(listItem) {
let enabled = enabledOptions.includes(listItem.label);
listItem.enabled = enabled;
listItem.element.setAttribute('class', enabled ? '' : 'disabled');
});
this._elContextMenu.style.display = "block";
this._elContextMenu.style.left
= Math.min(clickEvent.pageX, document.body.offsetWidth - this._elContextMenu.offsetWidth).toString() + "px";
this._elContextMenu.style.top
= Math.min(clickEvent.pageY, document.body.clientHeight - this._elContextMenu.offsetHeight).toString() + "px";
clickEvent.stopPropagation();
},
/**
* Set the callback for when a menu item is selected
* @param onSelectedCallback
*/
setOnSelectedCallback: function(onSelectedCallback) {
this._onSelectedCallback = onSelectedCallback;
},
/**
* Add a labeled item to the context menu
* @param itemLabel
* @private
*/
_addListItem: function(itemLabel) {
let elListItem = document.createElement("li");
elListItem.innerText = itemLabel;
let listItem = {
label: itemLabel,
element: elListItem,
enabled: false
};
elListItem.addEventListener("click", function () {
if (listItem.enabled && this._onSelectedCallback) {
this._onSelectedCallback.call(this, itemLabel, this._selectedEntityID);
}
}.bind(this), false);
elListItem.setAttribute('class', 'disabled');
this._listItems.push(listItem);
this._elContextMenu.appendChild(elListItem);
},
/**
* Add a separator item to the context menu
* @private
*/
_addListSeparator: function() {
let elListItem = document.createElement("li");
elListItem.setAttribute('class', 'separator');
this._elContextMenu.appendChild(elListItem);
},
/**
* Initialize the context menu.
* @private
*/
_initialize: function() {
this._elContextMenu = document.createElement("ul");
this._elContextMenu.setAttribute("class", CONTEXT_MENU_CLASS);
document.body.appendChild(this._elContextMenu);
this._addListItem("Cut");
this._addListItem("Copy");
this._addListItem("Copy ID(s)");
this._addListItem("Paste");
this._addListSeparator();
this._addListItem("Rename");
this._addListItem("Duplicate");
this._addListItem("Delete");
// Ignore clicks on context menu background or separator.
this._elContextMenu.addEventListener("click", function(event) {
// Sink clicks on context menu background or separator but let context menu item clicks through.
if (event.target.classList.contains(CONTEXT_MENU_CLASS)) {
event.stopPropagation();
}
});
// Provide means to close context menu without clicking menu item.
document.body.addEventListener("click", this.close.bind(this));
document.body.addEventListener("keydown", function(event) {
// Close context menu with Esc key.
if (this.isContextMenuOpen() && event.key === "Escape") {
this.close();
}
}.bind(this));
}
};