1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | import * as go from '../release/go-module.js';
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | export class OrthogonalLinkReshapingTool extends go.LinkReshapingTool {
|
22 | |
23 |
|
24 |
|
25 | constructor() {
|
26 | super();
|
27 | this.name = 'OrthogonalLinkReshaping';
|
28 | }
|
29 |
|
30 | private _alreadyAddedPoint: boolean = false;
|
31 |
|
32 | |
33 |
|
34 |
|
35 |
|
36 | public makeAdornment(pathshape: go.Shape): go.Adornment {
|
37 | const link = pathshape.part as go.Link;
|
38 |
|
39 |
|
40 | const adornment = super.makeAdornment(pathshape);
|
41 |
|
42 |
|
43 | if (link !== null && link.isOrthogonal && link.curve !== go.Link.Bezier) {
|
44 | const firstindex = link.firstPickIndex + (link.resegmentable ? 0 : 1);
|
45 | const lastindex = link.lastPickIndex - (link.resegmentable ? 0 : 1);
|
46 | for (let i = firstindex; i < lastindex; i++) {
|
47 | this.makeSegmentDragHandle(link, adornment, i);
|
48 | }
|
49 | }
|
50 | return adornment;
|
51 | }
|
52 |
|
53 | |
54 |
|
55 |
|
56 | public doDeactivate(): void {
|
57 | this._alreadyAddedPoint = false;
|
58 |
|
59 | const link = this.adornedLink;
|
60 | if (link !== null && link.isOrthogonal && link.curve !== go.Link.Bezier) {
|
61 | const pathshape = link.path;
|
62 | if (pathshape !== null) {
|
63 | const adornment = this.makeAdornment(pathshape);
|
64 | if (adornment !== null) {
|
65 | link.addAdornment(this.name, adornment);
|
66 | adornment.location = link.position;
|
67 | }
|
68 | }
|
69 | }
|
70 | super.doDeactivate();
|
71 | }
|
72 |
|
73 | |
74 |
|
75 |
|
76 |
|
77 | public reshape(newpt: go.Point): void {
|
78 | const link = this.adornedLink;
|
79 |
|
80 |
|
81 | if (link !== null && link.isOrthogonal && link.curve !== go.Link.Bezier && this.handle !== null && this.handle.toMaxLinks === 999) {
|
82 | link.startRoute();
|
83 | let index = this.handle.segmentIndex;
|
84 | if (!this._alreadyAddedPoint && link.resegmentable) {
|
85 | this._alreadyAddedPoint = true;
|
86 | if (index === link.firstPickIndex) {
|
87 | link.insertPoint(index, link.getPoint(index).copy());
|
88 | index++;
|
89 | this.handle.segmentIndex = index;
|
90 | } else if (index === link.lastPickIndex - 1) {
|
91 | link.insertPoint(index, link.getPoint(index).copy());
|
92 | if (index - 1 === link.firstPickIndex + 1) this.handle.segmentIndex = index - 1;
|
93 | }
|
94 | }
|
95 | const behavior = this.getReshapingBehavior(this.handle);
|
96 | if (behavior === go.LinkReshapingTool.Vertical) {
|
97 |
|
98 | link.setPointAt(index, link.getPoint(index - 1).x, newpt.y);
|
99 | link.setPointAt(index + 1, link.getPoint(index + 2).x, newpt.y);
|
100 | } else if (behavior === go.LinkReshapingTool.Horizontal) {
|
101 |
|
102 | link.setPointAt(index, newpt.x, link.getPoint(index - 1).y);
|
103 | link.setPointAt(index + 1, newpt.x, link.getPoint(index + 2).y);
|
104 | }
|
105 | link.commitRoute();
|
106 | } else {
|
107 | super.reshape(newpt);
|
108 | }
|
109 | }
|
110 |
|
111 | |
112 |
|
113 |
|
114 |
|
115 |
|
116 | public makeSegmentDragHandle(link: go.Link, adornment: go.Adornment, index: number): void {
|
117 | const a = link.getPoint(index);
|
118 | let b = link.getPoint(index + 1);
|
119 | const seglength = Math.max(Math.abs(a.x - b.x), Math.abs(a.y - b.y));
|
120 |
|
121 | let orient = '';
|
122 | if (this.isApprox(a.x, b.x) && this.isApprox(a.y, b.y)) {
|
123 | b = link.getPoint(index - 1);
|
124 | if (this.isApprox(a.x, b.x)) {
|
125 | orient = 'vertical';
|
126 | } else if (this.isApprox(a.y, b.y)) {
|
127 | orient = 'horizontal';
|
128 | }
|
129 | } else {
|
130 | if (this.isApprox(a.x, b.x)) {
|
131 | orient = 'vertical';
|
132 | } else if (this.isApprox(a.y, b.y)) {
|
133 | orient = 'horizontal';
|
134 | }
|
135 | }
|
136 |
|
137 |
|
138 | const h = new go.Shape();
|
139 | h.strokeWidth = 6;
|
140 | h.opacity = 0;
|
141 | h.segmentOrientation = go.Link.OrientAlong;
|
142 | h.segmentIndex = index;
|
143 | h.segmentFraction = 0.5;
|
144 | h.toMaxLinks = 999;
|
145 | if (orient === 'horizontal') {
|
146 | this.setReshapingBehavior(h, go.LinkReshapingTool.Vertical);
|
147 | h.cursor = 'n-resize';
|
148 | } else {
|
149 | this.setReshapingBehavior(h, go.LinkReshapingTool.Horizontal);
|
150 | h.cursor = 'w-resize';
|
151 | }
|
152 | h.geometryString = 'M 0 0 L ' + seglength + ' 0';
|
153 | adornment.insertAt(0, h);
|
154 | }
|
155 |
|
156 | |
157 |
|
158 |
|
159 |
|
160 | public isApprox(x: number, y: number): boolean {
|
161 | const d = x - y;
|
162 | return d < 0.5 && d > -0.5;
|
163 | }
|
164 | }
|