UNPKG

5.2 kBJavaScriptView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4/*
5* This is an extension and not part of the main GoJS library.
6* Note that the API for this class may change with any version, even point releases.
7* If you intend to use an extension in production, you should copy the code to your own source directory.
8* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
9* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
10*/
11import * as go from '../release/go-module.js';
12/**
13 * The LinkLabelOnPathDraggingTool class lets the user move a label on a {@link Link} while keeping the label on the link's path.
14 * This tool only works when the Link has a label marked by the "_isLinkLabel" property.
15 *
16 * If you want to experiment with this extension, try the <a href="../../extensionsJSM/LinkLabelOnPathDragging.html">Link Label On Path Dragging</a> sample.
17 * @category Tool Extension
18 */
19export class LinkLabelOnPathDraggingTool extends go.Tool {
20 /**
21 * Constructs a LinkLabelOnPathDraggingTool and sets the name for the tool.
22 */
23 constructor() {
24 super();
25 /**
26 * The label being dragged.
27 */
28 this.label = null;
29 this._originalFraction = 0.0;
30 this.name = 'LinkLabelOnPathDragging';
31 }
32 /**
33 * From the GraphObject at the mouse point, search up the visual tree until we get to
34 * an object that has the "_isLinkLabel" property set to true and that is an immediate child of a Link Panel.
35 * @return {GraphObject} This returns null if no such label is at the mouse down point.
36 */
37 findLabel() {
38 const diagram = this.diagram;
39 const e = diagram.lastInput;
40 let elt = diagram.findObjectAt(e.documentPoint, null, null);
41 if (elt === null || !(elt.part instanceof go.Link))
42 return null;
43 while (elt !== null && elt.panel !== elt.part) {
44 elt = elt.panel;
45 }
46 // If it's not marked as "_isLinkLabel", don't consider it a label:
47 if (!elt['_isLinkLabel'])
48 return null;
49 return elt;
50 }
51 /**
52 * This tool can only start if the mouse has moved enough so that it is not a click,
53 * and if the mouse down point is on a GraphObject "label" in a Link Panel,
54 * as determined by {@link #findLabel}.
55 */
56 canStart() {
57 if (!super.canStart())
58 return false;
59 const diagram = this.diagram;
60 // require left button & that it has moved far enough away from the mouse down point, so it isn't a click
61 const e = diagram.lastInput;
62 if (!e.left)
63 return false;
64 if (!this.isBeyondDragSize())
65 return false;
66 return this.findLabel() !== null;
67 }
68 /**
69 * Start a transaction, call findLabel and remember it as the "label" property,
70 * and remember the original values for the label's segment properties.
71 */
72 doActivate() {
73 this.startTransaction('Shifted Label');
74 this.label = this.findLabel();
75 if (this.label !== null) {
76 this._originalFraction = this.label.segmentFraction;
77 }
78 super.doActivate();
79 }
80 /**
81 * Stop any ongoing transaction.
82 */
83 doDeactivate() {
84 super.doDeactivate();
85 this.stopTransaction();
86 }
87 /**
88 * Clear any reference to a label element.
89 */
90 doStop() {
91 this.label = null;
92 super.doStop();
93 }
94 /**
95 * Restore the label's original value for GraphObject.segment... properties.
96 */
97 doCancel() {
98 if (this.label !== null) {
99 this.label.segmentFraction = this._originalFraction;
100 }
101 super.doCancel();
102 }
103 /**
104 * During the drag, call {@link #updateSegmentOffset} in order to set the segment... properties of the label.
105 */
106 doMouseMove() {
107 if (!this.isActive)
108 return;
109 this.updateSegmentOffset();
110 }
111 /**
112 * At the end of the drag, update the segment properties of the label and finish the tool,
113 * completing a transaction.
114 */
115 doMouseUp() {
116 if (!this.isActive)
117 return;
118 this.updateSegmentOffset();
119 this.transactionResult = 'Shifted Label';
120 this.stopTool();
121 }
122 /**
123 * Save the label's {@link GraphObject#segmentFraction}
124 * at the closest point to the mouse.
125 */
126 updateSegmentOffset() {
127 const lab = this.label;
128 if (lab === null)
129 return;
130 const link = lab.part;
131 if (!(link instanceof go.Link) || link.path === null)
132 return;
133 const last = this.diagram.lastInput.documentPoint;
134 // find the fractional distance along the link path closest to this point
135 const path = link.path;
136 if (path.geometry === null)
137 return;
138 const localpt = path.getLocalPoint(last);
139 lab.segmentFraction = path.geometry.getFractionForPoint(localpt);
140 }
141}