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