UNPKG

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