@easy-editor/plugin-dashboard 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -9
- package/README.md +123 -123
- package/dist/designer/alignment.d.ts +55 -0
- package/dist/designer/guideline.d.ts +93 -0
- package/dist/designer/marquee-selection.d.ts +38 -0
- package/dist/index.cjs +539 -34
- package/dist/index.d.ts +5 -0
- package/dist/index.js +533 -36
- package/dist/type.d.ts +10 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
var core = require('@easy-editor/core');
|
|
4
6
|
var mobx = require('mobx');
|
|
5
7
|
|
|
@@ -55,12 +57,12 @@ function _applyDecs2311(e, t, n, r, o, i) {
|
|
|
55
57
|
t[4](this, e);
|
|
56
58
|
}
|
|
57
59
|
} : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
|
|
58
|
-
if ((c = y[+s][r]) && 7
|
|
60
|
+
if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
|
|
59
61
|
y[+s][r] = o < 3 ? 1 : o;
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
|
|
63
|
-
var T = b(h[O], "A decorator", "be",
|
|
65
|
+
var T = b(h[O], "A decorator", "be", true),
|
|
64
66
|
z = n ? h[O - 1] : void 0,
|
|
65
67
|
A = {},
|
|
66
68
|
H = {
|
|
@@ -69,7 +71,7 @@ function _applyDecs2311(e, t, n, r, o, i) {
|
|
|
69
71
|
metadata: a,
|
|
70
72
|
addInitializer: function (e, t) {
|
|
71
73
|
if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
|
|
72
|
-
b(t, "An initializer", "be",
|
|
74
|
+
b(t, "An initializer", "be", true), i.push(t);
|
|
73
75
|
}.bind(null, A)
|
|
74
76
|
};
|
|
75
77
|
if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = {
|
|
@@ -93,8 +95,8 @@ function _applyDecs2311(e, t, n, r, o, i) {
|
|
|
93
95
|
}
|
|
94
96
|
function w(e) {
|
|
95
97
|
return m(e, d, {
|
|
96
|
-
configurable:
|
|
97
|
-
enumerable:
|
|
98
|
+
configurable: true,
|
|
99
|
+
enumerable: true,
|
|
98
100
|
value: a
|
|
99
101
|
});
|
|
100
102
|
}
|
|
@@ -140,7 +142,7 @@ function _toPrimitive(t, r) {
|
|
|
140
142
|
if ("object" != typeof t || !t) return t;
|
|
141
143
|
var e = t[Symbol.toPrimitive];
|
|
142
144
|
if (void 0 !== e) {
|
|
143
|
-
var i = e.call(t, r
|
|
145
|
+
var i = e.call(t, r);
|
|
144
146
|
if ("object" != typeof i) return i;
|
|
145
147
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
146
148
|
}
|
|
@@ -151,10 +153,144 @@ function _toPropertyKey(t) {
|
|
|
151
153
|
return "symbol" == typeof i ? i : i + "";
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
let _initProto
|
|
156
|
+
let _initProto$1;
|
|
157
|
+
let AlignType = /*#__PURE__*/function (AlignType) {
|
|
158
|
+
AlignType["LEFT"] = "left";
|
|
159
|
+
AlignType["RIGHT"] = "right";
|
|
160
|
+
AlignType["TOP"] = "top";
|
|
161
|
+
AlignType["BOTTOM"] = "bottom";
|
|
162
|
+
AlignType["HORIZONTAL_CENTER"] = "horizontalCenter";
|
|
163
|
+
AlignType["VERTICAL_CENTER"] = "verticalCenter";
|
|
164
|
+
return AlignType;
|
|
165
|
+
}({});
|
|
166
|
+
let DistributeType = /*#__PURE__*/function (DistributeType) {
|
|
167
|
+
DistributeType["HORIZONTAL"] = "horizontal";
|
|
168
|
+
DistributeType["VERTICAL"] = "vertical";
|
|
169
|
+
return DistributeType;
|
|
170
|
+
}({});
|
|
171
|
+
class Alignment {
|
|
172
|
+
static {
|
|
173
|
+
[_initProto$1] = _applyDecs2311(this, [], [[mobx.action, 2, "align"], [mobx.action, 2, "distribute"]]).e;
|
|
174
|
+
}
|
|
175
|
+
constructor(designer) {
|
|
176
|
+
this.designer = designer;
|
|
177
|
+
}
|
|
178
|
+
get selection() {
|
|
179
|
+
return this.designer.selection;
|
|
180
|
+
}
|
|
181
|
+
getSelectedNodes() {
|
|
182
|
+
return this.selection.getTopNodes(false).filter(node => node && !node.isRoot);
|
|
183
|
+
}
|
|
184
|
+
calculateBoundingBox(nodes) {
|
|
185
|
+
let [minX, minY, maxX, maxY] = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
|
|
186
|
+
for (const node of nodes) {
|
|
187
|
+
const rect = node.getDashboardRect();
|
|
188
|
+
minX = Math.min(minX, rect.x);
|
|
189
|
+
minY = Math.min(minY, rect.y);
|
|
190
|
+
maxX = Math.max(maxX, rect.x + rect.width);
|
|
191
|
+
maxY = Math.max(maxY, rect.y + rect.height);
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
minX,
|
|
195
|
+
minY,
|
|
196
|
+
maxX,
|
|
197
|
+
maxY,
|
|
198
|
+
width: maxX - minX,
|
|
199
|
+
height: maxY - minY
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
updateNodePosition(node, x, y) {
|
|
203
|
+
if (node.isGroup) {
|
|
204
|
+
const nodeRect = node.getDashboardRect();
|
|
205
|
+
const deltaX = x - nodeRect.x;
|
|
206
|
+
const deltaY = y - nodeRect.y;
|
|
207
|
+
for (const child of node.getAllNodesInGroup()) {
|
|
208
|
+
const childRect = child.getDashboardRect();
|
|
209
|
+
child.updateDashboardRect({
|
|
210
|
+
x: childRect.x + deltaX,
|
|
211
|
+
y: childRect.y + deltaY
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
node.updateDashboardRect({
|
|
216
|
+
x,
|
|
217
|
+
y
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
align(type) {
|
|
222
|
+
const nodes = this.getSelectedNodes();
|
|
223
|
+
if (nodes.length < 2) return false;
|
|
224
|
+
const box = this.calculateBoundingBox(nodes);
|
|
225
|
+
for (const node of nodes) {
|
|
226
|
+
const rect = node.getDashboardRect();
|
|
227
|
+
let newX = rect.x;
|
|
228
|
+
let newY = rect.y;
|
|
229
|
+
switch (type) {
|
|
230
|
+
case AlignType.LEFT:
|
|
231
|
+
newX = box.minX;
|
|
232
|
+
break;
|
|
233
|
+
case AlignType.RIGHT:
|
|
234
|
+
newX = box.maxX - rect.width;
|
|
235
|
+
break;
|
|
236
|
+
case AlignType.TOP:
|
|
237
|
+
newY = box.minY;
|
|
238
|
+
break;
|
|
239
|
+
case AlignType.BOTTOM:
|
|
240
|
+
newY = box.maxY - rect.height;
|
|
241
|
+
break;
|
|
242
|
+
case AlignType.HORIZONTAL_CENTER:
|
|
243
|
+
newX = box.minX + (box.width - rect.width) / 2;
|
|
244
|
+
break;
|
|
245
|
+
case AlignType.VERTICAL_CENTER:
|
|
246
|
+
newY = box.minY + (box.height - rect.height) / 2;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
this.updateNodePosition(node, newX, newY);
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
distribute(type) {
|
|
254
|
+
const nodes = this.getSelectedNodes();
|
|
255
|
+
if (nodes.length < 3) return false;
|
|
256
|
+
const box = this.calculateBoundingBox(nodes);
|
|
257
|
+
if (type === DistributeType.HORIZONTAL) {
|
|
258
|
+
const sorted = [...nodes].sort((a, b) => a.getDashboardRect().x - b.getDashboardRect().x);
|
|
259
|
+
const totalWidth = sorted.reduce((sum, n) => sum + n.getDashboardRect().width, 0);
|
|
260
|
+
const gap = (box.width - totalWidth) / (nodes.length - 1);
|
|
261
|
+
let currentX = box.minX;
|
|
262
|
+
for (const node of sorted) {
|
|
263
|
+
const rect = node.getDashboardRect();
|
|
264
|
+
this.updateNodePosition(node, currentX, rect.y);
|
|
265
|
+
currentX += rect.width + gap;
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
const sorted = [...nodes].sort((a, b) => a.getDashboardRect().y - b.getDashboardRect().y);
|
|
269
|
+
const totalHeight = sorted.reduce((sum, n) => sum + n.getDashboardRect().height, 0);
|
|
270
|
+
const gap = (box.height - totalHeight) / (nodes.length - 1);
|
|
271
|
+
let currentY = box.minY;
|
|
272
|
+
for (const node of sorted) {
|
|
273
|
+
const rect = node.getDashboardRect();
|
|
274
|
+
this.updateNodePosition(node, rect.x, currentY);
|
|
275
|
+
currentY += rect.height + gap;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
alignLeft = (_initProto$1(this), () => this.align(AlignType.LEFT));
|
|
281
|
+
alignRight = () => this.align(AlignType.RIGHT);
|
|
282
|
+
alignTop = () => this.align(AlignType.TOP);
|
|
283
|
+
alignBottom = () => this.align(AlignType.BOTTOM);
|
|
284
|
+
alignHorizontalCenter = () => this.align(AlignType.HORIZONTAL_CENTER);
|
|
285
|
+
alignVerticalCenter = () => this.align(AlignType.VERTICAL_CENTER);
|
|
286
|
+
distributeHorizontal = () => this.distribute(DistributeType.HORIZONTAL);
|
|
287
|
+
distributeVertical = () => this.distribute(DistributeType.VERTICAL);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
let _initProto, _init_enabled, _init_extra_enabled, _init_guideLines, _init_extra_guideLines, _init_nodeLineMap, _init_extra_nodeLineMap, _init_adsorptionLines, _init_extra_adsorptionLines, _init_adsorptionLinesWithDistance, _init_extra_adsorptionLinesWithDistance, _init_userGuideLines, _init_extra_userGuideLines;
|
|
155
291
|
class GuideLine {
|
|
156
292
|
static {
|
|
157
|
-
[_init_enabled, _init_extra_enabled, _init_guideLines, _init_extra_guideLines, _init_nodeLineMap, _init_extra_nodeLineMap, _init_adsorptionLines, _init_extra_adsorptionLines, _initProto] = _applyDecs2311(this, [], [[mobx.observable, 1, "enabled"], [[mobx.observable, mobx.observable.shallow], 17, "guideLines"], [mobx.computed, 3, "guideLinesMap"], [[mobx.observable, mobx.observable.shallow], 17, "nodeLineMap"], [mobx.observable, 1, "adsorptionLines"], [mobx.action, 2, "addGuideLine"], [mobx.action, 2, "removeGuideLine"], [mobx.action, 2, "updateGuideLine"], [mobx.action, 2, "calculateGuideLineInfo"], [mobx.action, 2, "getAdsorptionPosition"], [mobx.action, 2, "resetAdsorptionLines"]]).e;
|
|
293
|
+
[_init_enabled, _init_extra_enabled, _init_guideLines, _init_extra_guideLines, _init_nodeLineMap, _init_extra_nodeLineMap, _init_adsorptionLines, _init_extra_adsorptionLines, _init_adsorptionLinesWithDistance, _init_extra_adsorptionLinesWithDistance, _init_userGuideLines, _init_extra_userGuideLines, _initProto] = _applyDecs2311(this, [], [[mobx.observable, 1, "enabled"], [[mobx.observable, mobx.observable.shallow], 17, "guideLines"], [mobx.computed, 3, "guideLinesMap"], [[mobx.observable, mobx.observable.shallow], 17, "nodeLineMap"], [mobx.observable, 1, "adsorptionLines"], [[mobx.observable, mobx.observable.shallow], 17, "adsorptionLinesWithDistance"], [[mobx.observable, mobx.observable.shallow], 17, "userGuideLines"], [mobx.action, 2, "addGuideLine"], [mobx.action, 2, "removeGuideLine"], [mobx.action, 2, "updateGuideLine"], [mobx.computed, 3, "userGuideLinesMap"], [mobx.action, 2, "addUserGuideLine"], [mobx.action, 2, "updateUserGuideLine"], [mobx.action, 2, "removeUserGuideLine"], [mobx.action, 2, "clearUserGuideLines"], [mobx.action, 2, "calculateGuideLineInfo"], [mobx.action, 2, "getAdsorptionPosition"], [mobx.action, 2, "resetAdsorptionLines"]]).e;
|
|
158
294
|
}
|
|
159
295
|
#A = (_initProto(this), _init_enabled(this, true));
|
|
160
296
|
get enabled() {
|
|
@@ -197,6 +333,21 @@ class GuideLine {
|
|
|
197
333
|
set adsorptionLines(v) {
|
|
198
334
|
this.#D = v;
|
|
199
335
|
}
|
|
336
|
+
#E = (_init_extra_adsorptionLines(this), _init_adsorptionLinesWithDistance(this, []));
|
|
337
|
+
get adsorptionLinesWithDistance() {
|
|
338
|
+
return this.#E;
|
|
339
|
+
}
|
|
340
|
+
set adsorptionLinesWithDistance(v) {
|
|
341
|
+
this.#E = v;
|
|
342
|
+
}
|
|
343
|
+
#F = (_init_extra_adsorptionLinesWithDistance(this), _init_userGuideLines(this, []));
|
|
344
|
+
get userGuideLines() {
|
|
345
|
+
return this.#F;
|
|
346
|
+
}
|
|
347
|
+
set userGuideLines(v) {
|
|
348
|
+
this.#F = v;
|
|
349
|
+
}
|
|
350
|
+
userGuideLineIdCounter = (_init_extra_userGuideLines(this), 0);
|
|
200
351
|
get currentDocument() {
|
|
201
352
|
return this.designer.currentDocument;
|
|
202
353
|
}
|
|
@@ -252,6 +403,41 @@ class GuideLine {
|
|
|
252
403
|
this.guideLines[index] = guideLine;
|
|
253
404
|
}
|
|
254
405
|
}
|
|
406
|
+
get userGuideLinesMap() {
|
|
407
|
+
const result = Object.groupBy(this.userGuideLines, item => item.type);
|
|
408
|
+
return {
|
|
409
|
+
verticalLinesMap: new Map(result.vertical?.map(item => [item.position, item])),
|
|
410
|
+
horizontalLinesMap: new Map(result.horizontal?.map(item => [item.position, item]))
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
addUserGuideLine(type, position) {
|
|
414
|
+
const id = `user-guideline-${++this.userGuideLineIdCounter}`;
|
|
415
|
+
const guideLine = {
|
|
416
|
+
id,
|
|
417
|
+
type,
|
|
418
|
+
position: Math.round(position)
|
|
419
|
+
};
|
|
420
|
+
this.userGuideLines.push(guideLine);
|
|
421
|
+
return guideLine;
|
|
422
|
+
}
|
|
423
|
+
updateUserGuideLine(id, position) {
|
|
424
|
+
const index = this.userGuideLines.findIndex(item => item.id === id);
|
|
425
|
+
if (index !== -1) {
|
|
426
|
+
this.userGuideLines[index] = {
|
|
427
|
+
...this.userGuideLines[index],
|
|
428
|
+
position: Math.round(position)
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
removeUserGuideLine(id) {
|
|
433
|
+
const index = this.userGuideLines.findIndex(item => item.id === id);
|
|
434
|
+
if (index !== -1) {
|
|
435
|
+
this.userGuideLines.splice(index, 1);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
clearUserGuideLines() {
|
|
439
|
+
this.userGuideLines = [];
|
|
440
|
+
}
|
|
255
441
|
calculateGuideLineInfo() {
|
|
256
442
|
if (!this.enabled) return;
|
|
257
443
|
const verticalLinesMap = new Map();
|
|
@@ -288,7 +474,8 @@ class GuideLine {
|
|
|
288
474
|
this.nodeLineMap.verticalLinesMap = verticalLinesMap;
|
|
289
475
|
this.nodeLineMap.horizontalLinesMap = horizontalLinesMap;
|
|
290
476
|
}
|
|
291
|
-
adsorptionSize =
|
|
477
|
+
adsorptionSize = 10;
|
|
478
|
+
maxDistanceDisplay = 300;
|
|
292
479
|
getAdsorptionPosition(rect, adsorption) {
|
|
293
480
|
if (typeof adsorption === 'number') {
|
|
294
481
|
adsorption = [adsorption];
|
|
@@ -300,42 +487,63 @@ class GuideLine {
|
|
|
300
487
|
const currentHorizontalLine = [rect.top, rect.top + rect.height / 2, rect.bottom];
|
|
301
488
|
currentVerticalLine.forEach((item, index) => {
|
|
302
489
|
let minDistance = Number.POSITIVE_INFINITY;
|
|
490
|
+
let closestPosition = null;
|
|
303
491
|
this.nodeLineMap.verticalLinesMap.forEach((_, pos) => {
|
|
304
492
|
const distance = Math.abs(item - pos);
|
|
305
493
|
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
306
|
-
minDistance =
|
|
494
|
+
minDistance = distance;
|
|
495
|
+
closestPosition = pos;
|
|
307
496
|
}
|
|
308
497
|
});
|
|
309
498
|
this.guideLinesMap.verticalLinesMap.forEach((_, pos) => {
|
|
310
499
|
const distance = Math.abs(item - pos);
|
|
311
500
|
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
312
|
-
minDistance =
|
|
501
|
+
minDistance = distance;
|
|
502
|
+
closestPosition = pos;
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
this.userGuideLinesMap.verticalLinesMap.forEach((_, pos) => {
|
|
506
|
+
const distance = Math.abs(item - pos);
|
|
507
|
+
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
508
|
+
minDistance = distance;
|
|
509
|
+
closestPosition = pos;
|
|
313
510
|
}
|
|
314
511
|
});
|
|
315
|
-
if (
|
|
512
|
+
if (closestPosition !== null && adsorptionVerticalLines.findIndex(item => item.position === closestPosition) === -1) {
|
|
316
513
|
adsorptionVerticalLines.push({
|
|
317
514
|
adsorption: index,
|
|
318
|
-
position:
|
|
515
|
+
position: closestPosition
|
|
319
516
|
});
|
|
320
517
|
}
|
|
321
518
|
});
|
|
322
519
|
currentHorizontalLine.forEach((item, index) => {
|
|
323
|
-
let minDistance =
|
|
520
|
+
let minDistance = Number.POSITIVE_INFINITY;
|
|
521
|
+
let closestPosition = null;
|
|
324
522
|
this.nodeLineMap.horizontalLinesMap.forEach((_, pos) => {
|
|
325
|
-
|
|
326
|
-
|
|
523
|
+
const distance = Math.abs(item - pos);
|
|
524
|
+
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
525
|
+
minDistance = distance;
|
|
526
|
+
closestPosition = pos;
|
|
327
527
|
}
|
|
328
528
|
});
|
|
329
529
|
this.guideLinesMap.horizontalLinesMap.forEach((_, pos) => {
|
|
330
530
|
const distance = Math.abs(item - pos);
|
|
331
|
-
if (distance < this.adsorptionSize && distance < minDistance) {
|
|
332
|
-
minDistance =
|
|
531
|
+
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
532
|
+
minDistance = distance;
|
|
533
|
+
closestPosition = pos;
|
|
333
534
|
}
|
|
334
535
|
});
|
|
335
|
-
|
|
536
|
+
this.userGuideLinesMap.horizontalLinesMap.forEach((_, pos) => {
|
|
537
|
+
const distance = Math.abs(item - pos);
|
|
538
|
+
if (distance !== 0 && distance < this.adsorptionSize && distance < minDistance) {
|
|
539
|
+
minDistance = distance;
|
|
540
|
+
closestPosition = pos;
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
if (closestPosition !== null && adsorptionHorizontalLines.findIndex(item => item.position === closestPosition) === -1) {
|
|
336
544
|
adsorptionHorizontalLines.push({
|
|
337
545
|
adsorption: index,
|
|
338
|
-
position:
|
|
546
|
+
position: closestPosition
|
|
339
547
|
});
|
|
340
548
|
}
|
|
341
549
|
});
|
|
@@ -344,9 +552,32 @@ class GuideLine {
|
|
|
344
552
|
x: undefined,
|
|
345
553
|
y: undefined
|
|
346
554
|
};
|
|
555
|
+
const linesWithDistance = [];
|
|
347
556
|
if (isAdsorption) {
|
|
348
557
|
adsorptionVerticalLines.forEach(item => this.adsorptionLines.verticalLines.add(item.position));
|
|
349
558
|
adsorptionHorizontalLines.forEach(item => this.adsorptionLines.horizontalLines.add(item.position));
|
|
559
|
+
for (const line of adsorptionVerticalLines) {
|
|
560
|
+
const lineInfo = {
|
|
561
|
+
position: line.position,
|
|
562
|
+
type: 'vertical'
|
|
563
|
+
};
|
|
564
|
+
const segments = this.calculateVerticalLineSegments(rect, line.position);
|
|
565
|
+
if (segments.length > 0) {
|
|
566
|
+
lineInfo.distanceSegments = segments;
|
|
567
|
+
}
|
|
568
|
+
linesWithDistance.push(lineInfo);
|
|
569
|
+
}
|
|
570
|
+
for (const line of adsorptionHorizontalLines) {
|
|
571
|
+
const lineInfo = {
|
|
572
|
+
position: line.position,
|
|
573
|
+
type: 'horizontal'
|
|
574
|
+
};
|
|
575
|
+
const segments = this.calculateHorizontalLineSegments(rect, line.position);
|
|
576
|
+
if (segments.length > 0) {
|
|
577
|
+
lineInfo.distanceSegments = segments;
|
|
578
|
+
}
|
|
579
|
+
linesWithDistance.push(lineInfo);
|
|
580
|
+
}
|
|
350
581
|
if (adsorptionVerticalLines.length > 0) {
|
|
351
582
|
if (adsorption) {
|
|
352
583
|
adsorb.x = adsorptionVerticalLines.find(item => adsorption.includes(item.adsorption));
|
|
@@ -364,6 +595,7 @@ class GuideLine {
|
|
|
364
595
|
}
|
|
365
596
|
}
|
|
366
597
|
}
|
|
598
|
+
this.adsorptionLinesWithDistance = linesWithDistance;
|
|
367
599
|
return {
|
|
368
600
|
isAdsorption,
|
|
369
601
|
adsorb
|
|
@@ -372,6 +604,250 @@ class GuideLine {
|
|
|
372
604
|
resetAdsorptionLines() {
|
|
373
605
|
this.adsorptionLines.verticalLines.clear();
|
|
374
606
|
this.adsorptionLines.horizontalLines.clear();
|
|
607
|
+
this.adsorptionLinesWithDistance = [];
|
|
608
|
+
}
|
|
609
|
+
calculateVerticalLineSegments(rect, linePosition) {
|
|
610
|
+
const segments = [];
|
|
611
|
+
const selected = this.getSelectedNodeIds();
|
|
612
|
+
const nodes = [...this.currentDocument.nodesMap.values()].filter(node => !node.hidden && !selected.includes(node.id) && !node.isRoot && !node.isGroup);
|
|
613
|
+
let nearestAbove = null;
|
|
614
|
+
let nearestBelow = null;
|
|
615
|
+
for (const node of nodes) {
|
|
616
|
+
const nodeRect = node.getDashboardRect();
|
|
617
|
+
if (!nodeRect) continue;
|
|
618
|
+
const nodeLines = [nodeRect.left, nodeRect.left + nodeRect.width / 2, nodeRect.right];
|
|
619
|
+
const isOnLine = nodeLines.some(pos => Math.abs(pos - linePosition) < 1);
|
|
620
|
+
if (!isOnLine) continue;
|
|
621
|
+
if (nodeRect.bottom <= rect.top) {
|
|
622
|
+
const distance = rect.top - nodeRect.bottom;
|
|
623
|
+
if (!nearestAbove || distance < nearestAbove.distance) {
|
|
624
|
+
nearestAbove = {
|
|
625
|
+
distance,
|
|
626
|
+
nodeRect
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
} else if (nodeRect.top >= rect.bottom) {
|
|
630
|
+
const distance = nodeRect.top - rect.bottom;
|
|
631
|
+
if (!nearestBelow || distance < nearestBelow.distance) {
|
|
632
|
+
nearestBelow = {
|
|
633
|
+
distance,
|
|
634
|
+
nodeRect
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (nearestAbove && this.isDistanceInDisplayRange(nearestAbove.distance)) {
|
|
640
|
+
segments.push({
|
|
641
|
+
distance: Math.round(nearestAbove.distance),
|
|
642
|
+
start: nearestAbove.nodeRect.bottom,
|
|
643
|
+
end: rect.top,
|
|
644
|
+
fixedPos: linePosition,
|
|
645
|
+
labelPos: nearestAbove.nodeRect.bottom + nearestAbove.distance / 2
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
if (nearestBelow && this.isDistanceInDisplayRange(nearestBelow.distance)) {
|
|
649
|
+
segments.push({
|
|
650
|
+
distance: Math.round(nearestBelow.distance),
|
|
651
|
+
start: rect.bottom,
|
|
652
|
+
end: nearestBelow.nodeRect.top,
|
|
653
|
+
fixedPos: linePosition,
|
|
654
|
+
labelPos: rect.bottom + nearestBelow.distance / 2
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
return segments;
|
|
658
|
+
}
|
|
659
|
+
calculateHorizontalLineSegments(rect, linePosition) {
|
|
660
|
+
const segments = [];
|
|
661
|
+
const selected = this.getSelectedNodeIds();
|
|
662
|
+
const nodes = [...this.currentDocument.nodesMap.values()].filter(node => !node.hidden && !selected.includes(node.id) && !node.isRoot && !node.isGroup);
|
|
663
|
+
let nearestLeft = null;
|
|
664
|
+
let nearestRight = null;
|
|
665
|
+
for (const node of nodes) {
|
|
666
|
+
const nodeRect = node.getDashboardRect();
|
|
667
|
+
if (!nodeRect) continue;
|
|
668
|
+
const nodeLines = [nodeRect.top, nodeRect.top + nodeRect.height / 2, nodeRect.bottom];
|
|
669
|
+
const isOnLine = nodeLines.some(pos => Math.abs(pos - linePosition) < 1);
|
|
670
|
+
if (!isOnLine) continue;
|
|
671
|
+
if (nodeRect.right <= rect.left) {
|
|
672
|
+
const distance = rect.left - nodeRect.right;
|
|
673
|
+
if (!nearestLeft || distance < nearestLeft.distance) {
|
|
674
|
+
nearestLeft = {
|
|
675
|
+
distance,
|
|
676
|
+
nodeRect
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
} else if (nodeRect.left >= rect.right) {
|
|
680
|
+
const distance = nodeRect.left - rect.right;
|
|
681
|
+
if (!nearestRight || distance < nearestRight.distance) {
|
|
682
|
+
nearestRight = {
|
|
683
|
+
distance,
|
|
684
|
+
nodeRect
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (nearestLeft && this.isDistanceInDisplayRange(nearestLeft.distance)) {
|
|
690
|
+
segments.push({
|
|
691
|
+
distance: Math.round(nearestLeft.distance),
|
|
692
|
+
start: nearestLeft.nodeRect.right,
|
|
693
|
+
end: rect.left,
|
|
694
|
+
fixedPos: linePosition,
|
|
695
|
+
labelPos: nearestLeft.nodeRect.right + nearestLeft.distance / 2
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
if (nearestRight && this.isDistanceInDisplayRange(nearestRight.distance)) {
|
|
699
|
+
segments.push({
|
|
700
|
+
distance: Math.round(nearestRight.distance),
|
|
701
|
+
start: rect.right,
|
|
702
|
+
end: nearestRight.nodeRect.left,
|
|
703
|
+
fixedPos: linePosition,
|
|
704
|
+
labelPos: rect.right + nearestRight.distance / 2
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
return segments;
|
|
708
|
+
}
|
|
709
|
+
getSelectedNodeIds() {
|
|
710
|
+
const selected = [];
|
|
711
|
+
for (const node of this.designer.selection.getNodes()) {
|
|
712
|
+
if (node.isGroup) {
|
|
713
|
+
selected.push(...node.getAllNodesInGroup().map(n => n.id));
|
|
714
|
+
} else {
|
|
715
|
+
selected.push(node.id);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return selected;
|
|
719
|
+
}
|
|
720
|
+
isDistanceInDisplayRange(distance) {
|
|
721
|
+
return distance >= this.adsorptionSize && distance <= this.maxDistanceDisplay;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
class MarqueeSelection {
|
|
726
|
+
emitter = core.createEventBus('MarqueeEngine');
|
|
727
|
+
isMarqueeSelecting = false;
|
|
728
|
+
enabled = true;
|
|
729
|
+
constructor(designer) {
|
|
730
|
+
this.designer = designer;
|
|
731
|
+
}
|
|
732
|
+
isSelecting() {
|
|
733
|
+
return this.isMarqueeSelecting;
|
|
734
|
+
}
|
|
735
|
+
from(shell, viewport, isClickOnNode) {
|
|
736
|
+
if (!shell) {
|
|
737
|
+
return () => {};
|
|
738
|
+
}
|
|
739
|
+
let startX = 0;
|
|
740
|
+
let startY = 0;
|
|
741
|
+
let isCtrlPressed = false;
|
|
742
|
+
const masterSensors = this.getMasterSensors();
|
|
743
|
+
const calculateRect = (x1, y1, x2, y2) => {
|
|
744
|
+
return {
|
|
745
|
+
x: Math.min(x1, x2),
|
|
746
|
+
y: Math.min(y1, y2),
|
|
747
|
+
width: Math.abs(x2 - x1),
|
|
748
|
+
height: Math.abs(y2 - y1)
|
|
749
|
+
};
|
|
750
|
+
};
|
|
751
|
+
const move = e => {
|
|
752
|
+
const localPoint = viewport.toLocalPoint(e);
|
|
753
|
+
const currentX = localPoint.clientX;
|
|
754
|
+
const currentY = localPoint.clientY;
|
|
755
|
+
const marqueeRect = calculateRect(startX, startY, currentX, currentY);
|
|
756
|
+
this.emitter.emit('marquee', {
|
|
757
|
+
startX,
|
|
758
|
+
startY,
|
|
759
|
+
currentX,
|
|
760
|
+
currentY,
|
|
761
|
+
rect: marqueeRect,
|
|
762
|
+
isCtrlPressed: e.ctrlKey || e.metaKey
|
|
763
|
+
});
|
|
764
|
+
};
|
|
765
|
+
const over = e => {
|
|
766
|
+
const handleEvents = core.makeEventsHandler(e, masterSensors);
|
|
767
|
+
handleEvents(doc => {
|
|
768
|
+
doc.removeEventListener('mousemove', move, true);
|
|
769
|
+
doc.removeEventListener('mouseup', over, true);
|
|
770
|
+
});
|
|
771
|
+
const localPoint = viewport.toLocalPoint(e);
|
|
772
|
+
const currentX = localPoint.clientX;
|
|
773
|
+
const currentY = localPoint.clientY;
|
|
774
|
+
const marqueeRect = calculateRect(startX, startY, currentX, currentY);
|
|
775
|
+
this.isMarqueeSelecting = false;
|
|
776
|
+
this.designer.detecting.enable = true;
|
|
777
|
+
this.emitter.emit('marqueeEnd', {
|
|
778
|
+
startX,
|
|
779
|
+
startY,
|
|
780
|
+
currentX,
|
|
781
|
+
currentY,
|
|
782
|
+
rect: marqueeRect,
|
|
783
|
+
isCtrlPressed: e.ctrlKey || e.metaKey
|
|
784
|
+
});
|
|
785
|
+
};
|
|
786
|
+
const mousedown = e => {
|
|
787
|
+
if (e.button !== 0) return;
|
|
788
|
+
if (!this.enabled) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const target = e.target;
|
|
792
|
+
if (isClickOnNode(target)) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
e.preventDefault();
|
|
796
|
+
const localPoint = viewport.toLocalPoint(e);
|
|
797
|
+
startX = localPoint.clientX;
|
|
798
|
+
startY = localPoint.clientY;
|
|
799
|
+
isCtrlPressed = e.ctrlKey || e.metaKey;
|
|
800
|
+
const handleEvents = core.makeEventsHandler(e, masterSensors);
|
|
801
|
+
handleEvents(doc => {
|
|
802
|
+
doc.addEventListener('mousemove', move, true);
|
|
803
|
+
doc.addEventListener('mouseup', over, true);
|
|
804
|
+
});
|
|
805
|
+
this.emitter.emit('marqueeStart', {
|
|
806
|
+
startX,
|
|
807
|
+
startY,
|
|
808
|
+
currentX: startX,
|
|
809
|
+
currentY: startY,
|
|
810
|
+
rect: {
|
|
811
|
+
x: startX,
|
|
812
|
+
y: startY,
|
|
813
|
+
width: 0,
|
|
814
|
+
height: 0
|
|
815
|
+
},
|
|
816
|
+
isCtrlPressed
|
|
817
|
+
});
|
|
818
|
+
this.isMarqueeSelecting = true;
|
|
819
|
+
this.designer.detecting.enable = false;
|
|
820
|
+
};
|
|
821
|
+
shell.addEventListener('mousedown', mousedown);
|
|
822
|
+
return () => {
|
|
823
|
+
shell.removeEventListener('mousedown', mousedown);
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
onMarqueeStart(func) {
|
|
827
|
+
this.emitter.on('marqueeStart', func);
|
|
828
|
+
return () => {
|
|
829
|
+
this.emitter.off('marqueeStart', func);
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
onMarquee(func) {
|
|
833
|
+
this.emitter.on('marquee', func);
|
|
834
|
+
return () => {
|
|
835
|
+
this.emitter.off('marquee', func);
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
onMarqueeEnd(func) {
|
|
839
|
+
this.emitter.on('marqueeEnd', func);
|
|
840
|
+
return () => {
|
|
841
|
+
this.emitter.off('marqueeEnd', func);
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
getMasterSensors() {
|
|
845
|
+
return this.designer.project.documents.map(doc => {
|
|
846
|
+
if (doc.opened && doc.simulator?.sensorAvailable) {
|
|
847
|
+
return doc.simulator;
|
|
848
|
+
}
|
|
849
|
+
return null;
|
|
850
|
+
}).filter(Boolean);
|
|
375
851
|
}
|
|
376
852
|
}
|
|
377
853
|
|
|
@@ -523,10 +999,11 @@ const DashboardPlugin = options => {
|
|
|
523
999
|
x: boxX = 0,
|
|
524
1000
|
y: boxY = 0
|
|
525
1001
|
} = startOffsetNodes.box;
|
|
1002
|
+
const currentRect = new DOMRect(e.canvasX - boxX, e.canvasY - boxY, width, height);
|
|
526
1003
|
const {
|
|
527
1004
|
isAdsorption,
|
|
528
1005
|
adsorb
|
|
529
|
-
} = designer.guideline.getAdsorptionPosition(
|
|
1006
|
+
} = designer.guideline.getAdsorptionPosition(currentRect);
|
|
530
1007
|
let adsorbX = undefined;
|
|
531
1008
|
let adsorbY = undefined;
|
|
532
1009
|
if (isAdsorption) {
|
|
@@ -616,6 +1093,8 @@ const DashboardPlugin = options => {
|
|
|
616
1093
|
Node
|
|
617
1094
|
} = extendClass;
|
|
618
1095
|
let guideline = null;
|
|
1096
|
+
let alignment = null;
|
|
1097
|
+
let marqueeSelection = null;
|
|
619
1098
|
extend('Designer', {
|
|
620
1099
|
guideline: {
|
|
621
1100
|
get() {
|
|
@@ -624,6 +1103,22 @@ const DashboardPlugin = options => {
|
|
|
624
1103
|
}
|
|
625
1104
|
return guideline;
|
|
626
1105
|
}
|
|
1106
|
+
},
|
|
1107
|
+
alignment: {
|
|
1108
|
+
get() {
|
|
1109
|
+
if (!alignment) {
|
|
1110
|
+
alignment = new Alignment(this);
|
|
1111
|
+
}
|
|
1112
|
+
return alignment;
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
1115
|
+
marqueeSelection: {
|
|
1116
|
+
get() {
|
|
1117
|
+
if (!marqueeSelection) {
|
|
1118
|
+
marqueeSelection = new MarqueeSelection(this);
|
|
1119
|
+
}
|
|
1120
|
+
return marqueeSelection;
|
|
1121
|
+
}
|
|
627
1122
|
}
|
|
628
1123
|
});
|
|
629
1124
|
extend('Document', {
|
|
@@ -633,18 +1128,21 @@ const DashboardPlugin = options => {
|
|
|
633
1128
|
let nodeList = [];
|
|
634
1129
|
if (typeof nodeIdList[0] === 'string') {
|
|
635
1130
|
nodeList = nodeIdList.map(id => this.getNode(id));
|
|
1131
|
+
} else {
|
|
1132
|
+
nodeList = nodeIdList;
|
|
636
1133
|
}
|
|
1134
|
+
nodeList = nodeList.filter(node => node && !node.isRoot);
|
|
1135
|
+
if (nodeList.length === 0) return;
|
|
1136
|
+
const targetParent = nodeList[0].parent || this.rootNode;
|
|
637
1137
|
const groupNode = this.createNode(groupInitSchema);
|
|
638
|
-
let
|
|
1138
|
+
let minIndex = Number.POSITIVE_INFINITY;
|
|
639
1139
|
for (const node of nodeList) {
|
|
640
|
-
if (node.index <
|
|
641
|
-
|
|
642
|
-
}
|
|
643
|
-
if (node && !node.isRoot) {
|
|
644
|
-
this.migrateNode(node, groupNode);
|
|
1140
|
+
if (node.index < minIndex) {
|
|
1141
|
+
minIndex = node.index;
|
|
645
1142
|
}
|
|
1143
|
+
this.migrateNode(node, groupNode);
|
|
646
1144
|
}
|
|
647
|
-
|
|
1145
|
+
targetParent?.insert(groupNode, minIndex);
|
|
648
1146
|
return groupNode;
|
|
649
1147
|
}
|
|
650
1148
|
},
|
|
@@ -657,11 +1155,12 @@ const DashboardPlugin = options => {
|
|
|
657
1155
|
groupNode = group;
|
|
658
1156
|
}
|
|
659
1157
|
if (!groupNode || !groupNode.isGroup || !groupNode.children) return;
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
1158
|
+
const parent = groupNode.parent;
|
|
1159
|
+
if (!parent) return;
|
|
1160
|
+
groupNode.index;
|
|
1161
|
+
const nodes = [...groupNode.childrenNodes];
|
|
1162
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
1163
|
+
this.migrateNode(nodes[i], parent);
|
|
665
1164
|
}
|
|
666
1165
|
this.removeNode(groupNode);
|
|
667
1166
|
}
|
|
@@ -882,4 +1381,10 @@ const calculateDashboardRectBox = nodes => {
|
|
|
882
1381
|
return new DOMRect(minX, minY, maxX - minX, maxY - minY);
|
|
883
1382
|
};
|
|
884
1383
|
|
|
885
|
-
|
|
1384
|
+
exports.AlignType = AlignType;
|
|
1385
|
+
exports.Alignment = Alignment;
|
|
1386
|
+
exports.DistributeType = DistributeType;
|
|
1387
|
+
exports.GuideLine = GuideLine;
|
|
1388
|
+
exports.default = DashboardPlugin;
|
|
1389
|
+
exports.updateNodeRect = updateNodeRect;
|
|
1390
|
+
exports.updateNodeRectByDOM = updateNodeRectByDOM;
|