DraggingTool class
The DraggingTool is used to move or copy selected parts with the mouse. This sets the Part#location property; you may want to save the location to the model by using a TwoWay Binding on the "location" property in your Parts/Nodes/Groups templates.
Dragging the selection moves parts for which Part#canMove is true. If the user holds down the Control key (Option key on Mac), this tool will make a copy of the parts being dragged, for those parts for which Part#canCopy is true.
When the drag starts it calls #computeEffectiveCollection to find the actual collection of Parts to be dragged. Normally this collection includes not only the Diagram#selection, but also parts that belong to those selected parts, such as members of groups. If #dragsTree is true, the effective collection also includes all of the nodes and links that constitute the subtree starting from selected nodes. The result of #computeEffectiveCollection is not a Set but a Map which remembers the original Part#location for all of the dragged parts. This map is saved as the value of #draggedParts.
During the drag if the user holds down the Control/Option key this tool makes a copy of the #draggedParts and proceeds to drag it around. (It only copies the Diagram#selection, not the whole effective collection, if #copiesEffectiveCollection is false.) The collection of copied parts is held by #copiedParts. It too is a Map remembering the original locations of the parts. #copiedParts will be null when this tool is moving (not copying) at the moment.
Each Part's movement is limited by the Diagram#computeMove method. By default it limits the Part#location to be within the bounds given by Part#minLocation and Part#maxLocation. (Those default to minus Infinity to plus Infinity.) As a further convenience, the value of NaN in minLocation and maxLocation cause Diagram#computeMove to use the part's current location. So, for example, an easy way to declare that the user may only drag a node horizontally is to just set:
$(go.Node,
. . .
{ minLocation: new go.Point(-Infinity, NaN), maxLocation: new go.Point(Infinity, NaN) },
. . .
)
If you set #isGridSnapEnabled to true, dragged or copied parts will be snapped to points on a grid. The snapping occurs continuously during a drag unless you set #isGridSnapRealtime to false. Normally the grid points come from the Diagram#grid, even if that grid is not GraphObject#visible. However you can override those grid's properties for the snapping grid cell size and offset by setting the properties here: #gridSnapCellSize and #gridSnapOrigin. This computes the point to snap to for each dragged part. The resulting point is used as the new Part#location.
For the most general control over where a part may be dragged, either set the Part#dragComputation property or override Diagram#computeMove. For the common case of wanting to keep member nodes within the Group that they are members of, you can do something like:
// this is a Part.dragComputation function for limiting where a Node may be dragged
function stayInGroup(part, pt, gridpt) {
// don't constrain top-level nodes
var grp = part.containingGroup;
if (grp === null) return pt;
// try to stay within the background Shape of the Group
var back = grp.resizeObject;
if (back === null) return pt;
// allow dragging a Node out of a Group if the Shift key is down
if (part.diagram.lastInput.shift) return pt;
var p1 = back.getDocumentPoint(go.Spot.TopLeft);
var p2 = back.getDocumentPoint(go.Spot.BottomRight);
var b = part.actualBounds;
var loc = part.location;
// find the padding inside the group's placeholder that is around the member parts
var m = grp.placeholder.padding;
// now limit the location appropriately, assuming no grid-snapping
var x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x-b.x);
var y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y-b.y);
return new go.Point(x, y);
}
Note that this expects there to be a "SHAPE" object within the Group's visual tree that delimits where the part may be dragged within the group. This also expects that Group#computesBoundsIncludingLinks is false. Then in your node template(s), just set:
$(go.Node,
. . .,
{ dragComputation: stayInGroup },
. . .
)
This tool does not utilize any Adornments or tool handles. If the drag is successful, it raises the "SelectionMoved" or "SelectionCopied" DiagramEvent and produces a "Move" or a "Copy" transaction.
If you want to programmatically start a new user's dragging of a particular existing node, you can make sure that node is selected, set the #currentPart property, and then start and activate the tool.
var node = ...;
myDiagram.select(node); // in this case the only selected node
var tool = myDiagram.toolManager.draggingTool;
tool.currentPart = node; // the DraggingTool will not call standardMouseSelect
myDiagram.currentTool = tool; // starts the DraggingTool
tool.doActivate(); // activates the DraggingTool
- Implemented types
- Available extensions
- Annotations
-
- @JS()
- @staticInterop
Constructors
- DraggingTool()
-
factory
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited