mirror of https://github.com/node-red/node-red.git
177 lines
6.2 KiB
JavaScript
177 lines
6.2 KiB
JavaScript
RED.contextMenu = (function() {
|
|
|
|
let menu;
|
|
function createMenu() {
|
|
// menu = RED.popover.menu({
|
|
// options: [
|
|
// {
|
|
// label: 'delete selection',
|
|
// onselect: function() {
|
|
// RED.actions.invoke('core:delete-selection')
|
|
// RED.view.focus()
|
|
// }
|
|
// },
|
|
// { label: 'world' }
|
|
// ],
|
|
// width: 200,
|
|
// })
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
function disposeMenu() {
|
|
$(document).off("mousedown.red-ui-workspace-context-menu");
|
|
if (menu) {
|
|
menu.remove();
|
|
}
|
|
menu = null;
|
|
}
|
|
function show(options) {
|
|
if (menu) {
|
|
menu.remove()
|
|
}
|
|
|
|
const selection = RED.view.selection()
|
|
const hasSelection = (selection.nodes && selection.nodes.length > 0);
|
|
const hasMultipleSelection = hasSelection && selection.nodes.length > 1;
|
|
const hasLinks = selection.links && selection.links.length > 0;
|
|
const isSingleLink = !hasSelection && hasLinks && selection.links.length === 1
|
|
const isMultipleLinks = !hasSelection && hasLinks && selection.links.length > 1
|
|
const canDelete = hasSelection || hasLinks
|
|
const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group'
|
|
|
|
const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g
|
|
|
|
|
|
const menuItems = [
|
|
{ onselect: 'core:show-action-list', onpostselect: function() {} },
|
|
{
|
|
label: RED._("contextMenu.insert"),
|
|
options: [
|
|
{
|
|
label: RED._("contextMenu.node"),
|
|
onselect: function() {
|
|
RED.view.showQuickAddDialog({
|
|
position: [ options.x - offset.left, options.y - offset.top ],
|
|
touchTrigger: true,
|
|
splice: isSingleLink?selection.links[0]:undefined,
|
|
// spliceMultiple: isMultipleLinks
|
|
})
|
|
}
|
|
},
|
|
{
|
|
label: RED._("contextMenu.junction"),
|
|
onselect: 'core:split-wires-with-junctions',
|
|
disabled: hasSelection || !hasLinks
|
|
},
|
|
{
|
|
label: RED._("contextMenu.linkNodes"),
|
|
onselect: 'core:split-wire-with-link-nodes',
|
|
disabled: hasSelection || !hasLinks
|
|
}
|
|
]
|
|
|
|
|
|
|
|
}
|
|
]
|
|
// menuItems.push(
|
|
// {
|
|
// label: (isSingleLink || isMultipleLinks)?'Insert into wire...':'Add node...',
|
|
// onselect: function() {
|
|
// RED.view.showQuickAddDialog({
|
|
// position: [ options.x - offset.left, options.y - offset.top ],
|
|
// touchTrigger: true,
|
|
// splice: isSingleLink?selection.links[0]:undefined,
|
|
// spliceMultiple: isMultipleLinks
|
|
// })
|
|
// }
|
|
// },
|
|
// )
|
|
// if (hasLinks && !hasSelection) {
|
|
// menuItems.push({ onselect: 'core:split-wires-with-junctions', label: 'Insert junction'})
|
|
// }
|
|
menuItems.push(
|
|
null,
|
|
{ onselect: 'core:undo', disabled: RED.history.list().length === 0 },
|
|
{ onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
|
|
null,
|
|
{ onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !hasSelection},
|
|
{ onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
|
|
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !RED.view.clipboard() },
|
|
{ onselect: 'core:delete-selection', disabled: !canDelete },
|
|
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
|
|
{ onselect: 'core:select-all-nodes' }
|
|
)
|
|
|
|
if (hasSelection) {
|
|
menuItems.push(
|
|
null,
|
|
isGroup ?
|
|
{ onselect: 'core:ungroup-selection', disabled: !isGroup }
|
|
: { onselect: 'core:group-selection', disabled: !hasSelection }
|
|
)
|
|
if (canRemoveFromGroup) {
|
|
menuItems.push({ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") })
|
|
}
|
|
|
|
}
|
|
const offset = $("#red-ui-workspace-chart").offset()
|
|
menu = RED.menu.init({
|
|
direction: 'right',
|
|
onpreselect: function() {
|
|
disposeMenu()
|
|
},
|
|
onpostselect: function() {
|
|
RED.view.focus()
|
|
},
|
|
options: menuItems
|
|
});
|
|
|
|
menu.attr("id","red-ui-workspace-context-menu");
|
|
menu.css({
|
|
position: "absolute"
|
|
})
|
|
menu.appendTo("body");
|
|
|
|
// TODO: prevent the menu from overflowing the window.
|
|
|
|
var top = options.y
|
|
var left = options.x
|
|
|
|
if (top+menu.height()-$(document).scrollTop() > $(window).height()) {
|
|
top -= (top+menu.height())-$(window).height() + 22;
|
|
}
|
|
if (left+menu.width()-$(document).scrollLeft() > $(window).width()) {
|
|
left -= (left+menu.width())-$(window).width() + 18;
|
|
}
|
|
menu.css({
|
|
top: top+"px",
|
|
left: left+"px"
|
|
})
|
|
$(".red-ui-menu.red-ui-menu-dropdown").hide();
|
|
$(document).on("mousedown.red-ui-workspace-context-menu", function(evt) {
|
|
if (menu && menu[0].contains(evt.target)) {
|
|
return
|
|
}
|
|
disposeMenu()
|
|
});
|
|
menu.show();
|
|
|
|
// menu.show({
|
|
// target: $('#red-ui-main-container'),
|
|
// x: options.x,
|
|
// y: options.y
|
|
// })
|
|
|
|
|
|
}
|
|
|
|
return {
|
|
show: show,
|
|
hide: disposeMenu
|
|
}
|
|
})()
|