1 |
|
2 |
|
3 |
|
4 |
|
5 | import * as go from '../release/go-module.js';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | export class SpotRotatingTool extends go.RotatingTool {
|
16 | private _spotAdornmentTemplate: go.Adornment;
|
17 | private _originalRotationSpot: go.Spot = go.Spot.Default;
|
18 |
|
19 | public constructor() {
|
20 | super();
|
21 | const $ = go.GraphObject.make;
|
22 | this._spotAdornmentTemplate =
|
23 | $(go.Adornment, "Spot",
|
24 | { locationSpot: go.Spot.Center, cursor: "move" },
|
25 | $(go.Shape, "Circle",
|
26 | { fill: "lightblue", stroke: "dodgerblue", width: 10, height: 10 }),
|
27 | $(go.Shape, "Circle",
|
28 | { fill: "dodgerblue", strokeWidth: 0, width: 4, height: 4 })
|
29 | );
|
30 | }
|
31 |
|
32 | |
33 |
|
34 |
|
35 |
|
36 |
|
37 | updateAdornments(part: go.Part): void {
|
38 | super.updateAdornments(part);
|
39 | if (part === null) return;
|
40 | if (part.isSelected && !this.diagram.isReadOnly) {
|
41 | const rotateObj = part.rotateObject;
|
42 | if (rotateObj !== null && part.canRotate() && part.actualBounds.isReal() &&
|
43 | part.isVisible() && rotateObj.actualBounds.isReal() && rotateObj.isVisibleObject()) {
|
44 | let ad = part.findAdornment("RotateSpot");
|
45 | if (ad === null || ad.adornedObject !== rotateObj) {
|
46 | ad = this._spotAdornmentTemplate.copy();
|
47 | ad.adornedObject = part.rotateObject;
|
48 | }
|
49 | if (ad !== null) {
|
50 | ad.location = this.computeRotationPoint(ad.adornedObject);
|
51 | part.addAdornment("RotateSpot", ad);
|
52 | return;
|
53 | }
|
54 | }
|
55 | }
|
56 | part.removeAdornment("RotateSpot");
|
57 | };
|
58 |
|
59 | |
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | computeAdornmentLocation(obj: go.GraphObject): go.Point {
|
68 | let p = this.rotationPoint;
|
69 | if (!p.isReal()) p = this.computeRotationPoint(obj);
|
70 | const q = obj.getLocalPoint(p);
|
71 |
|
72 | q.x = Math.max(obj.naturalBounds.right, q.x) + this.handleDistance;
|
73 | return obj.getDocumentPoint(q);
|
74 | }
|
75 |
|
76 | |
77 |
|
78 |
|
79 |
|
80 |
|
81 | canStart(): boolean {
|
82 | if (!this.isEnabled) return false;
|
83 | const diagram = this.diagram;
|
84 | if (diagram.isReadOnly) return false;
|
85 | if (!diagram.allowRotate) return false;
|
86 | if (!diagram.lastInput.left) return false;
|
87 |
|
88 | let h = this.findToolHandleAt(diagram.firstInput.documentPoint, this.name);
|
89 | if (h !== null) return true;
|
90 |
|
91 | h = this.findToolHandleAt(diagram.firstInput.documentPoint, "RotateSpot");
|
92 | return (h !== null);
|
93 | }
|
94 |
|
95 | |
96 |
|
97 |
|
98 | doActivate(): void {
|
99 |
|
100 | this.handle = this.findToolHandleAt(this.diagram.firstInput.documentPoint, "RotateSpot");
|
101 | if (this.handle !== null) {
|
102 | const ad = this.handle.part as go.Adornment;
|
103 | if (ad.adornedObject !== null) {
|
104 | const part = ad.adornedPart;
|
105 | if (part !== null) this._originalRotationSpot = part.rotationSpot;
|
106 | }
|
107 | }
|
108 |
|
109 | super.doActivate();
|
110 | }
|
111 |
|
112 | |
113 |
|
114 |
|
115 | doCancel(): void {
|
116 | if (this.adornedObject !== null) {
|
117 | const part = this.adornedObject.part;
|
118 | if (part !== null) {
|
119 | part.rotationSpot = this._originalRotationSpot;
|
120 | this.rotationPoint.set(this.computeRotationPoint(this.adornedObject));
|
121 | this.updateAdornments(part);
|
122 | }
|
123 | }
|
124 | super.doCancel();
|
125 | }
|
126 |
|
127 | |
128 |
|
129 |
|
130 | doMouseMove(): void {
|
131 | if (this.isActive) {
|
132 | if (this.handle !== null && this.handle.part && this.handle.part.category === "RotateSpot") {
|
133 |
|
134 | this.shiftRotationPoint();
|
135 | } else {
|
136 | super.doMouseMove();
|
137 | }
|
138 | }
|
139 | }
|
140 |
|
141 | |
142 |
|
143 |
|
144 | doMouseUp(): void {
|
145 | if (this.isActive) {
|
146 | if (this.handle !== null && this.handle.part && this.handle.part.category === "RotateSpot") {
|
147 |
|
148 | this.shiftRotationPoint();
|
149 | this.transactionResult = "Shifted rotationSpot";
|
150 | this.stopTool();
|
151 | } else {
|
152 | super.doMouseUp();
|
153 | }
|
154 | }
|
155 | }
|
156 |
|
157 | |
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | shiftRotationPoint(): void {
|
168 | const dp = this.diagram.lastInput.documentPoint;
|
169 | const obj = this.adornedObject;
|
170 | if (obj === null) return;
|
171 | const w = obj.naturalBounds.width || 1;
|
172 | const h = obj.naturalBounds.height || 1;
|
173 | const part = obj.part;
|
174 | if (part === null) return;
|
175 | const op = obj.getLocalPoint(dp);
|
176 | const fx = (op.x < 0) ? 0 : (op.x > w ? 1 : op.x/w);
|
177 | const fy = (op.y < 0) ? 0 : (op.y > h ? 1 : op.y/h);
|
178 | const ox = (op.x < 0) ? op.x : (op.x > w ? op.x-w : 0);
|
179 | const oy = (op.y < 0) ? op.y : (op.y > h ? op.y-h : 0);
|
180 | part.rotationSpot = new go.Spot(fx, fy, ox, oy);
|
181 | this.rotationPoint.set(this.computeRotationPoint(obj));
|
182 | this.updateAdornments(part);
|
183 | }
|
184 | }
|