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 RowResizingTool extends go.Tool {
|
22 | private _handleArchetype: go.GraphObject;
|
23 | private _tableName: string = 'TABLE';
|
24 |
|
25 |
|
26 | private _handle: go.GraphObject | null = null;
|
27 | private _adornedTable: go.Panel | null = null;
|
28 |
|
29 | |
30 |
|
31 |
|
32 | constructor() {
|
33 | super();
|
34 | const h: go.Shape = new go.Shape();
|
35 | h.geometryString = 'M0 0 H14 M0 2 H14';
|
36 | h.desiredSize = new go.Size(14, 2);
|
37 | h.cursor = 'row-resize';
|
38 | h.geometryStretch = go.GraphObject.None;
|
39 | h.background = 'rgba(255,255,255,0.5)';
|
40 | h.stroke = 'rgba(30,144,255,0.5)';
|
41 | this._handleArchetype = h;
|
42 | this.name = 'RowResizing';
|
43 | }
|
44 |
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | get handleArchetype(): go.GraphObject { return this._handleArchetype; }
|
52 | set handleArchetype(val: go.GraphObject) { this._handleArchetype = val; }
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 | get tableName(): string { return this._tableName; }
|
60 | set tableName(val: string) { this._tableName = val; }
|
61 |
|
62 | |
63 |
|
64 |
|
65 |
|
66 |
|
67 | get handle(): go.GraphObject | null { return this._handle; }
|
68 |
|
69 | |
70 |
|
71 |
|
72 |
|
73 | get adornedTable(): go.Panel | null { return this._adornedTable; }
|
74 |
|
75 | |
76 |
|
77 |
|
78 |
|
79 |
|
80 | public updateAdornments(part: go.Part): void {
|
81 | if (part === null || part instanceof go.Link) return;
|
82 | if (part.isSelected && !this.diagram.isReadOnly) {
|
83 | const selelt = part.findObject(this.tableName);
|
84 | if (selelt instanceof go.Panel && selelt.actualBounds.isReal() && selelt.isVisibleObject() &&
|
85 | part.actualBounds.isReal() && part.isVisible() &&
|
86 | selelt.type === go.Panel.Table) {
|
87 | const table = selelt;
|
88 | let adornment = part.findAdornment(this.name);
|
89 | if (adornment === null) {
|
90 | adornment = this.makeAdornment(table);
|
91 | part.addAdornment(this.name, adornment);
|
92 | }
|
93 | if (adornment !== null) {
|
94 | const pad = table.padding as go.Margin;
|
95 | const numrows = table.rowCount;
|
96 |
|
97 | adornment.elements.each((h) => {
|
98 | if (!h.pickable) return;
|
99 | const rowdef = table.getRowDefinition(h.row);
|
100 | let hgt = rowdef.actual;
|
101 | if (hgt > 0) hgt = rowdef.total;
|
102 | let sep = 0;
|
103 |
|
104 | let idx = h.row + 1;
|
105 | while (idx < numrows && table.getRowDefinition(idx).actual === 0) idx++;
|
106 | if (idx < numrows) {
|
107 | sep = table.getRowDefinition(idx).separatorStrokeWidth;
|
108 | if (isNaN(sep)) sep = table.defaultRowSeparatorStrokeWidth;
|
109 | }
|
110 | h.alignment = new go.Spot(0, 0, pad.left + h.width / 2, pad.top + rowdef.position + hgt + sep / 2);
|
111 | });
|
112 | adornment.locationObject.desiredSize = table.actualBounds.size;
|
113 | adornment.location = table.getDocumentPoint(adornment.locationSpot);
|
114 | adornment.angle = table.getDocumentAngle();
|
115 | return;
|
116 | }
|
117 | }
|
118 | }
|
119 | part.removeAdornment(this.name);
|
120 | }
|
121 |
|
122 | |
123 |
|
124 |
|
125 |
|
126 |
|
127 | public makeAdornment(table: go.Panel): go.Adornment {
|
128 |
|
129 | const adornment = new go.Adornment();
|
130 | adornment.category = this.name;
|
131 | adornment.adornedObject = table;
|
132 | adornment.type = go.Panel.Spot;
|
133 | adornment.locationObjectName = 'BLOCK';
|
134 |
|
135 | const block = new go.TextBlock();
|
136 | block.name = 'BLOCK';
|
137 | block.pickable = false;
|
138 | adornment.add(block);
|
139 |
|
140 | for (let i = 0; i < table.rowCount; i++) {
|
141 | const rowdef = table.getRowDefinition(i);
|
142 | const h = this.makeHandle(table, rowdef);
|
143 | if (h !== null) adornment.add(h);
|
144 | }
|
145 | return adornment;
|
146 | }
|
147 |
|
148 | |
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | public makeHandle(table: go.Panel, rowdef: go.RowColumnDefinition): go.GraphObject | null {
|
155 | const h = this.handleArchetype;
|
156 | if (h === null) return null;
|
157 | const c = h.copy();
|
158 | c.row = rowdef.index;
|
159 | return c;
|
160 | }
|
161 |
|
162 |
|
163 | |
164 |
|
165 |
|
166 |
|
167 |
|
168 | public canStart(): boolean {
|
169 | if (!this.isEnabled) return false;
|
170 |
|
171 | const diagram = this.diagram;
|
172 | if (diagram.isReadOnly) return false;
|
173 | if (!diagram.lastInput.left) return false;
|
174 | const h = this.findToolHandleAt(diagram.firstInput.documentPoint, this.name);
|
175 | return (h !== null);
|
176 | }
|
177 |
|
178 | |
179 |
|
180 |
|
181 |
|
182 |
|
183 | public doActivate(): void {
|
184 | const diagram = this.diagram;
|
185 | this._handle = this.findToolHandleAt(diagram.firstInput.documentPoint, this.name);
|
186 | if (this.handle === null) return;
|
187 | const panel = (this.handle.part as go.Adornment).adornedObject as go.Adornment;
|
188 | if (!panel || panel.type !== go.Panel.Table) return;
|
189 | this._adornedTable = panel;
|
190 | diagram.isMouseCaptured = true;
|
191 | this.startTransaction(this.name);
|
192 | this.isActive = true;
|
193 | }
|
194 |
|
195 | |
196 |
|
197 |
|
198 | public doDeactivate(): void {
|
199 | this.stopTransaction();
|
200 | this._handle = null;
|
201 | this._adornedTable = null;
|
202 | const diagram = this.diagram;
|
203 | diagram.isMouseCaptured = false;
|
204 | this.isActive = false;
|
205 | }
|
206 |
|
207 | |
208 |
|
209 |
|
210 |
|
211 | public doMouseMove(): void {
|
212 | const diagram = this.diagram;
|
213 | if (this.isActive) {
|
214 | const newpt = this.computeResize(diagram.lastInput.documentPoint);
|
215 | this.resize(newpt);
|
216 | }
|
217 | }
|
218 |
|
219 | |
220 |
|
221 |
|
222 |
|
223 | public doMouseUp(): void {
|
224 | const diagram = this.diagram;
|
225 | if (this.isActive) {
|
226 | const newpt = this.computeResize(diagram.lastInput.documentPoint);
|
227 | this.resize(newpt);
|
228 | this.transactionResult = this.name;
|
229 | }
|
230 | this.stopTool();
|
231 | }
|
232 |
|
233 | |
234 |
|
235 |
|
236 |
|
237 |
|
238 | public resize(newPoint: go.Point): void {
|
239 | const table = this.adornedTable;
|
240 | if (table === null) return;
|
241 | const h = this.handle;
|
242 | if (h === null) return;
|
243 | const pad = table.padding as go.Margin;
|
244 | const numrows = table.rowCount;
|
245 | const locpt = table.getLocalPoint(newPoint);
|
246 | const rowdef = table.getRowDefinition(h.row);
|
247 | let sep = 0;
|
248 | let idx = h.row + 1;
|
249 | while (idx < numrows && table.getRowDefinition(idx).actual === 0) idx++;
|
250 | if (idx < numrows) {
|
251 | sep = table.getRowDefinition(idx).separatorStrokeWidth;
|
252 | if (isNaN(sep)) sep = table.defaultRowSeparatorStrokeWidth;
|
253 | }
|
254 | rowdef.height = Math.max(0, locpt.y - pad.top - rowdef.position - (rowdef.total - rowdef.actual) - sep / 2);
|
255 | }
|
256 |
|
257 |
|
258 | |
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 | public computeResize(p: go.Point): go.Point {
|
265 | return p;
|
266 | }
|
267 |
|
268 | |
269 |
|
270 |
|
271 | public doKeyDown(): void {
|
272 | if (!this.isActive) return;
|
273 | const diagram = this.diagram;
|
274 | const e = diagram.lastInput;
|
275 | if (e.key === 'Del' || e.key === '\t') {
|
276 | if (this.adornedTable !== null && this.handle !== null) {
|
277 | const rowdef = this.adornedTable.getRowDefinition(this.handle.row);
|
278 | rowdef.height = NaN;
|
279 | this.transactionResult = this.name;
|
280 | this.stopTool();
|
281 | }
|
282 | } else {
|
283 | super.doKeyDown();
|
284 | }
|
285 | }
|
286 |
|
287 | }
|