207 lines
9.0 KiB
HTML
207 lines
9.0 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>GoJS Context Menus -- Northwoods Software</title>
|
|
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
|
|
<script src="../release/go.js"></script>
|
|
<script src="goIntro.js"></script>
|
|
</head>
|
|
<body onload="goIntro()">
|
|
<div id="container" class="container-fluid">
|
|
<div id="content">
|
|
|
|
<h1>Context Menus</h1>
|
|
<p>
|
|
<b>GoJS</b> provides a mechanism for you to define context menus for any object or for the diagram background.
|
|
</p>
|
|
<p>
|
|
A context menu is an <a>Adornment</a> that is shown when the user context-clicks (right mouse clicks) an object
|
|
that has its <a>GraphObject.contextMenu</a> set.
|
|
The context menu is bound to the same data as the part itself.
|
|
</p>
|
|
<p>
|
|
See samples that make use of context menus in the <a href="../samples/index.html#contextmenus">samples index</a>.
|
|
</p>
|
|
<p>
|
|
It is typical to have the Adornment be a "Vertical" <a>Panel</a> containing "ContextMenuButton"s,
|
|
as you can see in the code below in the assignment of the Node's <a>GraphObject.contextMenu</a> and <a>Diagram.contextMenu</a> properties.
|
|
Each "ContextMenuButton" is a Panel on which you can set the <a>GraphObject.click</a> event handler.
|
|
In the event handler <code>obj.part</code> will be the whole context menu Adornment.
|
|
<code>obj.part.adornedPart</code> will be adorned Node or Link.
|
|
The bound data is <code>obj.part.data</code>, which will be the same as <code>obj.part.adornedPart.data</code>.
|
|
</p>
|
|
<p>
|
|
In this example each <a>Node</a> has its <a>GraphObject.contextMenu</a> property set to an Adornment that shows
|
|
a single button that when clicked changes the color property of the bound model data.
|
|
The diagram gets its own context menu by setting <a>Diagram.contextMenu</a>.
|
|
</p>
|
|
<pre data-language="javascript" id="contextmenus">
|
|
// This method is called as a context menu button's click handler.
|
|
// Rotate the selected node's color through a predefined sequence of colors.
|
|
function changeColor(e, obj) {
|
|
diagram.startTransaction("changed color");
|
|
// get the context menu that holds the button that was clicked
|
|
var contextmenu = obj.part;
|
|
// get the node data to which the Node is data bound
|
|
var nodedata = contextmenu.data;
|
|
// compute the next color for the node
|
|
var newcolor = "lightblue";
|
|
switch (nodedata.color) {
|
|
case "lightblue": newcolor = "lightgreen"; break;
|
|
case "lightgreen": newcolor = "lightyellow"; break;
|
|
case "lightyellow": newcolor = "orange"; break;
|
|
case "orange": newcolor = "lightblue"; break;
|
|
}
|
|
// modify the node data
|
|
// this evaluates data Bindings and records changes in the UndoManager
|
|
diagram.model.setDataProperty(nodedata, "color", newcolor);
|
|
diagram.commitTransaction("changed color");
|
|
}
|
|
|
|
// this is a normal Node template that also has a contextMenu defined for it
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape, "RoundedRectangle",
|
|
{ fill: "white" },
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock, { margin: 5 },
|
|
new go.Binding("text", "key")),
|
|
{
|
|
contextMenu: // define a context menu for each node
|
|
$(go.Adornment, "Vertical", // that has one button
|
|
$("ContextMenuButton",
|
|
$(go.TextBlock, "Change Color"),
|
|
{ click: changeColor })
|
|
// more ContextMenuButtons would go here
|
|
) // end Adornment
|
|
}
|
|
);
|
|
|
|
// also define a context menu for the diagram's background
|
|
diagram.contextMenu =
|
|
$(go.Adornment, "Vertical",
|
|
$("ContextMenuButton",
|
|
$(go.TextBlock, "Undo"),
|
|
{ click: function(e, obj) { e.diagram.commandHandler.undo(); } },
|
|
new go.Binding("visible", "", function(o) {
|
|
return o.diagram.commandHandler.canUndo();
|
|
}).ofObject()),
|
|
$("ContextMenuButton",
|
|
$(go.TextBlock, "Redo"),
|
|
{ click: function(e, obj) { e.diagram.commandHandler.redo(); } },
|
|
new go.Binding("visible", "", function(o) {
|
|
return o.diagram.commandHandler.canRedo();
|
|
}).ofObject()),
|
|
// no binding, always visible button:
|
|
$("ContextMenuButton",
|
|
$(go.TextBlock, "New Node"),
|
|
{ click: function(e, obj) {
|
|
var diagram = e.diagram;
|
|
diagram.startTransaction('new node');
|
|
var data = {};
|
|
diagram.model.addNodeData(data);
|
|
part = diagram.findPartForData(data);
|
|
part.location = diagram.toolManager.contextMenuTool.mouseDownPoint;
|
|
diagram.commitTransaction('new node');
|
|
} })
|
|
);
|
|
|
|
diagram.initialContentAlignment = go.Spot.Center;
|
|
|
|
var nodeDataArray = [
|
|
{ key: "Alpha", color: "lightyellow" },
|
|
{ key: "Beta", color: "orange" }
|
|
];
|
|
var linkDataArray = [
|
|
{ from: "Alpha", to: "Beta" }
|
|
];
|
|
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
|
|
diagram.undoManager.isEnabled = true;
|
|
</pre>
|
|
<script>goCode("contextmenus", 350, 200)</script>
|
|
<p>
|
|
Try context clicking a node and invoking the "Change Color" command a few times.
|
|
With the diagram context menu you will be able to "Undo" and/or "Redo", or you can use Control-Z and/or Control-Y.
|
|
</p>
|
|
|
|
<h3 id="Positioning">Positioning</h3>
|
|
<p>
|
|
There are two ways to customize the positioning of the context menu relative to the adorned GraphObject.
|
|
One way is to override <a>ContextMenuTool.positionContextMenu</a>.
|
|
Another way is to have the context menu <a>Adornment</a> include a <a>Placeholder</a>.
|
|
The Placeholder is positioned to have the same size and position as the adorned object.
|
|
</p>
|
|
<pre data-language="javascript" id="contextmenusplaceholder">
|
|
// this is a shared context menu button click event handler, just for demonstration
|
|
function cmCommand(e, obj) {
|
|
var node = obj.part.adornedPart; // the Node with the context menu
|
|
var buttontext = obj.elt(1); // the TextBlock
|
|
alert(buttontext.text + " command on " + node.data.key);
|
|
}
|
|
|
|
// this is a normal Node template that also has a contextMenu defined for it
|
|
diagram.nodeTemplate =
|
|
$(go.Node, "Auto",
|
|
$(go.Shape, "RoundedRectangle",
|
|
{ fill: "white" },
|
|
new go.Binding("fill", "color")),
|
|
$(go.TextBlock, { margin: 5 },
|
|
new go.Binding("text", "key")),
|
|
{
|
|
contextMenu: // define a context menu for each node
|
|
$(go.Adornment, "Spot", // that has several buttons around
|
|
$(go.Placeholder, { padding: 5 }), // a Placeholder object
|
|
$("ContextMenuButton", $(go.TextBlock, "Top"),
|
|
{ alignment: go.Spot.Top, alignmentFocus: go.Spot.Bottom, click: cmCommand }),
|
|
$("ContextMenuButton", $(go.TextBlock, "Right"),
|
|
{ alignment: go.Spot.Right, alignmentFocus: go.Spot.Left, click: cmCommand }),
|
|
$("ContextMenuButton", $(go.TextBlock, "Bottom"),
|
|
{ alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top, click: cmCommand }),
|
|
$("ContextMenuButton", $(go.TextBlock, "Left"),
|
|
{ alignment: go.Spot.Left, alignmentFocus: go.Spot.Right, click: cmCommand })
|
|
) // end Adornment
|
|
}
|
|
);
|
|
|
|
diagram.initialContentAlignment = go.Spot.Center;
|
|
var nodeDataArray = [
|
|
{ key: "Alpha", color: "lightyellow" },
|
|
{ key: "Beta", color: "orange" }
|
|
];
|
|
var linkDataArray = [
|
|
{ from: "Alpha", to: "Beta" }
|
|
];
|
|
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
|
|
</pre>
|
|
<script>goCode("contextmenusplaceholder", 350, 200)</script>
|
|
|
|
<h2 id="HTMLContextMenus">HTML Context Menus</h2>
|
|
<p>
|
|
It is possible to define custom context menus using HTML instead of Adornments using the <a>HTMLInfo</a> class.
|
|
The <a href="../samples/customContextMenu.html">Custom Context Menu sample</a> and
|
|
<a href="../samples/htmlLightBoxContextMenu.html">Lightbox Context Menu sample</a> show two such custom context menus.
|
|
See <a href="HTMLInteraction.html">HTMLInteraction</a> for more discussion.
|
|
</p>
|
|
|
|
<h2 id="DefaultContextMenuForTouchEnabledDevices">Default Context Menu for Touch-enabled devices</h2>
|
|
<p>
|
|
Touch devices are presumed to have no keyboard ability, which makes actions like copying and pasting more difficult.
|
|
Because of this, <b>GoJS</b> provides a built-in default context menu on touch devices, implemented in HTML.
|
|
The buttons on this menu are populated dynamically, depending on the target GraphObject (if any) and Diagram and their properties.
|
|
</p>
|
|
<p>
|
|
The default context menu can be disabled by setting <a>ContextMenuTool.defaultTouchContextMenu</a> to null.
|
|
The <a href="../samples/htmlLightBoxContextMenu.html">Lightbox Context Menu sample</a> contains a re-implementation of this menu if you wish to modify it.
|
|
</p>
|
|
<p>
|
|
If you define your own custom context menus, they will prevent the default context menu from appearing on touch devices.
|
|
We recommend that your custom context menus include common commands appropriate for your app.
|
|
</p>
|
|
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|