@eclipse-glsp/client 2.2.0-next.332 → 2.2.0-next.334
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/css/change-bounds.css +36 -2
- package/css/glsp-sprotty.css +18 -2
- package/css/helper-lines.css +3 -3
- package/lib/base/default.module.d.ts.map +1 -1
- package/lib/base/default.module.js +3 -0
- package/lib/base/default.module.js.map +1 -1
- package/lib/base/feedback/css-feedback.d.ts +7 -2
- package/lib/base/feedback/css-feedback.d.ts.map +1 -1
- package/lib/base/feedback/css-feedback.js +10 -2
- package/lib/base/feedback/css-feedback.js.map +1 -1
- package/lib/base/feedback/feeback-emitter.d.ts +2 -2
- package/lib/base/feedback/feeback-emitter.d.ts.map +1 -1
- package/lib/base/feedback/feeback-emitter.js +5 -2
- package/lib/base/feedback/feeback-emitter.js.map +1 -1
- package/lib/base/index.d.ts +1 -0
- package/lib/base/index.d.ts.map +1 -1
- package/lib/base/index.js +1 -0
- package/lib/base/index.js.map +1 -1
- package/lib/base/model/diagram-loader.d.ts.map +1 -1
- package/lib/base/model/diagram-loader.js +6 -1
- package/lib/base/model/diagram-loader.js.map +1 -1
- package/lib/base/mouse-position-tracker.d.ts +22 -0
- package/lib/base/mouse-position-tracker.d.ts.map +1 -0
- package/lib/base/mouse-position-tracker.js +40 -0
- package/lib/base/mouse-position-tracker.js.map +1 -0
- package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts +2 -0
- package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts.map +1 -1
- package/lib/features/accessibility/view-key-tools/movement-key-tool.js +15 -7
- package/lib/features/accessibility/view-key-tools/movement-key-tool.js.map +1 -1
- package/lib/features/bounds/bounds-module.d.ts.map +1 -1
- package/lib/features/bounds/bounds-module.js +2 -0
- package/lib/features/bounds/bounds-module.js.map +1 -1
- package/lib/features/bounds/freeform-layout.d.ts +17 -1
- package/lib/features/bounds/freeform-layout.d.ts.map +1 -1
- package/lib/features/bounds/freeform-layout.js +14 -5
- package/lib/features/bounds/freeform-layout.js.map +1 -1
- package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts +5 -4
- package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts.map +1 -1
- package/lib/features/bounds/glsp-hidden-bounds-updater.js +51 -39
- package/lib/features/bounds/glsp-hidden-bounds-updater.js.map +1 -1
- package/lib/features/bounds/hbox-layout.d.ts +18 -2
- package/lib/features/bounds/hbox-layout.d.ts.map +1 -1
- package/lib/features/bounds/hbox-layout.js +14 -5
- package/lib/features/bounds/hbox-layout.js.map +1 -1
- package/lib/features/bounds/index.d.ts +1 -0
- package/lib/features/bounds/index.d.ts.map +1 -1
- package/lib/features/bounds/index.js +1 -0
- package/lib/features/bounds/index.js.map +1 -1
- package/lib/features/bounds/layout-data.d.ts +27 -0
- package/lib/features/bounds/layout-data.d.ts.map +1 -0
- package/lib/features/bounds/layout-data.js +48 -0
- package/lib/features/bounds/layout-data.js.map +1 -0
- package/lib/features/bounds/local-bounds.d.ts +3 -1
- package/lib/features/bounds/local-bounds.d.ts.map +1 -1
- package/lib/features/bounds/local-bounds.js +14 -0
- package/lib/features/bounds/local-bounds.js.map +1 -1
- package/lib/features/bounds/vbox-layout.d.ts +18 -2
- package/lib/features/bounds/vbox-layout.d.ts.map +1 -1
- package/lib/features/bounds/vbox-layout.js +14 -5
- package/lib/features/bounds/vbox-layout.js.map +1 -1
- package/lib/features/change-bounds/index.d.ts +1 -0
- package/lib/features/change-bounds/index.d.ts.map +1 -1
- package/lib/features/change-bounds/index.js +1 -0
- package/lib/features/change-bounds/index.js.map +1 -1
- package/lib/features/change-bounds/model.d.ts +19 -3
- package/lib/features/change-bounds/model.d.ts.map +1 -1
- package/lib/features/change-bounds/model.js +92 -4
- package/lib/features/change-bounds/model.js.map +1 -1
- package/lib/features/change-bounds/movement-restrictor.d.ts +1 -0
- package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
- package/lib/features/change-bounds/movement-restrictor.js +7 -1
- package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
- package/lib/features/change-bounds/point-position-updater.d.ts +3 -0
- package/lib/features/change-bounds/point-position-updater.d.ts.map +1 -1
- package/lib/features/change-bounds/point-position-updater.js +7 -2
- package/lib/features/change-bounds/point-position-updater.js.map +1 -1
- package/lib/features/change-bounds/position-snapper.d.ts +4 -0
- package/lib/features/change-bounds/position-snapper.d.ts.map +1 -1
- package/lib/features/change-bounds/position-snapper.js +4 -0
- package/lib/features/change-bounds/position-snapper.js.map +1 -1
- package/lib/features/change-bounds/snap.d.ts +6 -0
- package/lib/features/change-bounds/snap.d.ts.map +1 -1
- package/lib/features/change-bounds/snap.js +6 -0
- package/lib/features/change-bounds/snap.js.map +1 -1
- package/lib/features/change-bounds/tracker.d.ts +32 -0
- package/lib/features/change-bounds/tracker.d.ts.map +1 -0
- package/lib/features/change-bounds/tracker.js +60 -0
- package/lib/features/change-bounds/tracker.js.map +1 -0
- package/lib/features/debug/debug-bounds-decorator.d.ts +4 -1
- package/lib/features/debug/debug-bounds-decorator.d.ts.map +1 -1
- package/lib/features/debug/debug-bounds-decorator.js +14 -7
- package/lib/features/debug/debug-bounds-decorator.js.map +1 -1
- package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts +9 -22
- package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts.map +1 -1
- package/lib/features/element-template/mouse-tracking-element-position-listener.js +30 -46
- package/lib/features/element-template/mouse-tracking-element-position-listener.js.map +1 -1
- package/lib/features/helper-lines/helper-line-feedback.d.ts +2 -2
- package/lib/features/helper-lines/helper-line-feedback.d.ts.map +1 -1
- package/lib/features/helper-lines/helper-line-feedback.js +1 -1
- package/lib/features/helper-lines/helper-line-feedback.js.map +1 -1
- package/lib/features/helper-lines/helper-line-manager-default.d.ts +2 -1
- package/lib/features/helper-lines/helper-line-manager-default.d.ts.map +1 -1
- package/lib/features/helper-lines/helper-line-manager-default.js +23 -0
- package/lib/features/helper-lines/helper-line-manager-default.js.map +1 -1
- package/lib/features/helper-lines/helper-line-manager.d.ts +10 -2
- package/lib/features/helper-lines/helper-line-manager.d.ts.map +1 -1
- package/lib/features/routing/edge-router.d.ts +4 -0
- package/lib/features/routing/edge-router.d.ts.map +1 -1
- package/lib/features/routing/edge-router.js +37 -0
- package/lib/features/routing/edge-router.js.map +1 -1
- package/lib/features/select/select-mouse-listener.d.ts +3 -0
- package/lib/features/select/select-mouse-listener.d.ts.map +1 -1
- package/lib/features/select/select-mouse-listener.js +30 -2
- package/lib/features/select/select-mouse-listener.js.map +1 -1
- package/lib/features/tools/base-tools.d.ts +24 -15
- package/lib/features/tools/base-tools.d.ts.map +1 -1
- package/lib/features/tools/base-tools.js +0 -18
- package/lib/features/tools/base-tools.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-manager.d.ts +42 -0
- package/lib/features/tools/change-bounds/change-bounds-manager.d.ts.map +1 -0
- package/lib/features/tools/change-bounds/change-bounds-manager.js +136 -0
- package/lib/features/tools/change-bounds/change-bounds-manager.js.map +1 -0
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts +6 -0
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js +14 -8
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-module.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-module.js +2 -0
- package/lib/features/tools/change-bounds/change-bounds-tool-module.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts +6 -15
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js +24 -72
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool.d.ts +14 -25
- package/lib/features/tools/change-bounds/change-bounds-tool.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool.js +63 -109
- package/lib/features/tools/change-bounds/change-bounds-tool.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts +136 -0
- package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts.map +1 -0
- package/lib/features/tools/change-bounds/change-bounds-tracker.js +301 -0
- package/lib/features/tools/change-bounds/change-bounds-tracker.js.map +1 -0
- package/lib/features/tools/change-bounds/index.d.ts +2 -0
- package/lib/features/tools/change-bounds/index.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/index.js +2 -0
- package/lib/features/tools/change-bounds/index.js.map +1 -1
- package/lib/features/tools/change-bounds/view.d.ts.map +1 -1
- package/lib/features/tools/change-bounds/view.js +1 -16
- package/lib/features/tools/change-bounds/view.js.map +1 -1
- package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts +7 -9
- package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts.map +1 -1
- package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js +27 -47
- package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js.map +1 -1
- package/lib/features/tools/edge-edit/edge-edit-tool.d.ts +2 -2
- package/lib/features/tools/edge-edit/edge-edit-tool.d.ts.map +1 -1
- package/lib/features/tools/edge-edit/edge-edit-tool.js +5 -5
- package/lib/features/tools/edge-edit/edge-edit-tool.js.map +1 -1
- package/lib/features/tools/marquee-selection/marquee-mouse-tool.d.ts +1 -0
- package/lib/features/tools/marquee-selection/marquee-mouse-tool.d.ts.map +1 -1
- package/lib/features/tools/marquee-selection/marquee-mouse-tool.js +3 -0
- package/lib/features/tools/marquee-selection/marquee-mouse-tool.js.map +1 -1
- package/lib/features/tools/node-creation/node-creation-tool.d.ts +2 -4
- package/lib/features/tools/node-creation/node-creation-tool.d.ts.map +1 -1
- package/lib/features/tools/node-creation/node-creation-tool.js +8 -11
- package/lib/features/tools/node-creation/node-creation-tool.js.map +1 -1
- package/lib/features/viewport/viewport-handler.d.ts +6 -4
- package/lib/features/viewport/viewport-handler.d.ts.map +1 -1
- package/lib/features/viewport/viewport-handler.js +13 -8
- package/lib/features/viewport/viewport-handler.js.map +1 -1
- package/lib/utils/gmodel-util.d.ts +20 -1
- package/lib/utils/gmodel-util.d.ts.map +1 -1
- package/lib/utils/gmodel-util.js +38 -16
- package/lib/utils/gmodel-util.js.map +1 -1
- package/lib/utils/layout-utils.d.ts +1 -0
- package/lib/utils/layout-utils.d.ts.map +1 -1
- package/lib/utils/layout-utils.js +5 -1
- package/lib/utils/layout-utils.js.map +1 -1
- package/package.json +3 -3
- package/src/base/default.module.ts +4 -1
- package/src/base/feedback/css-feedback.ts +10 -2
- package/src/base/feedback/feeback-emitter.ts +6 -3
- package/src/base/index.ts +1 -0
- package/src/base/model/diagram-loader.ts +5 -1
- package/src/base/mouse-position-tracker.ts +25 -0
- package/src/features/accessibility/view-key-tools/movement-key-tool.ts +12 -7
- package/src/features/bounds/bounds-module.ts +2 -0
- package/src/features/bounds/freeform-layout.ts +16 -6
- package/src/features/bounds/glsp-hidden-bounds-updater.ts +63 -46
- package/src/features/bounds/hbox-layout.ts +18 -9
- package/src/features/bounds/index.ts +1 -0
- package/src/features/bounds/layout-data.ts +48 -0
- package/src/features/bounds/local-bounds.ts +20 -4
- package/src/features/bounds/vbox-layout.ts +18 -10
- package/src/features/change-bounds/index.ts +1 -0
- package/src/features/change-bounds/model.ts +104 -4
- package/src/features/change-bounds/movement-restrictor.ts +10 -0
- package/src/features/change-bounds/point-position-updater.spec.ts +2 -0
- package/src/features/change-bounds/point-position-updater.ts +6 -0
- package/src/features/change-bounds/position-snapper.ts +4 -0
- package/src/features/change-bounds/snap.ts +6 -0
- package/src/features/change-bounds/tracker.ts +63 -0
- package/src/features/debug/debug-bounds-decorator.tsx +17 -7
- package/src/features/element-template/mouse-tracking-element-position-listener.ts +49 -71
- package/src/features/helper-lines/helper-line-feedback.ts +2 -1
- package/src/features/helper-lines/helper-line-manager-default.ts +37 -2
- package/src/features/helper-lines/helper-line-manager.ts +11 -2
- package/src/features/routing/edge-router.ts +42 -0
- package/src/features/select/select-mouse-listener.ts +15 -1
- package/src/features/tools/base-tools.ts +31 -19
- package/src/features/tools/change-bounds/change-bounds-manager.ts +145 -0
- package/src/features/tools/change-bounds/change-bounds-tool-feedback.ts +17 -6
- package/src/features/tools/change-bounds/change-bounds-tool-module.ts +2 -0
- package/src/features/tools/change-bounds/change-bounds-tool-move-feedback.ts +31 -81
- package/src/features/tools/change-bounds/change-bounds-tool.ts +89 -148
- package/src/features/tools/change-bounds/change-bounds-tracker.ts +455 -0
- package/src/features/tools/change-bounds/index.ts +2 -0
- package/src/features/tools/change-bounds/view.tsx +2 -14
- package/src/features/tools/edge-edit/edge-edit-tool-feedback.ts +34 -52
- package/src/features/tools/edge-edit/edge-edit-tool.ts +4 -3
- package/src/features/tools/marquee-selection/marquee-mouse-tool.ts +4 -0
- package/src/features/tools/node-creation/node-creation-tool.ts +7 -7
- package/src/features/viewport/viewport-handler.ts +13 -7
- package/src/utils/gmodel-util.ts +41 -5
- package/src/utils/layout-utils.ts +4 -0
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
Point,
|
|
28
28
|
TYPES,
|
|
29
29
|
Viewport,
|
|
30
|
+
equalUpTo,
|
|
30
31
|
findParentByFeature,
|
|
31
32
|
isBoundsAware,
|
|
32
33
|
isDecoration,
|
|
@@ -293,7 +294,7 @@ export class DrawHelperLinesFeedbackCommand extends FeedbackCommand {
|
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
protected isMatch(leftCoordinate: number, rightCoordinate: number, epsilon: number): boolean {
|
|
296
|
-
return
|
|
297
|
+
return equalUpTo(leftCoordinate, rightCoordinate, epsilon);
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
protected log(message: string, ...params: any[]): void {
|
|
@@ -13,7 +13,18 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
Action,
|
|
18
|
+
GModelElement,
|
|
19
|
+
GModelRoot,
|
|
20
|
+
IActionHandler,
|
|
21
|
+
MoveAction,
|
|
22
|
+
Point,
|
|
23
|
+
SetBoundsAction,
|
|
24
|
+
TYPES,
|
|
25
|
+
Vector,
|
|
26
|
+
Writable
|
|
27
|
+
} from '@eclipse-glsp/sprotty';
|
|
17
28
|
import { inject, injectable, optional, postConstruct } from 'inversify';
|
|
18
29
|
import { FeedbackEmitter } from '../../base';
|
|
19
30
|
import { IFeedbackActionDispatcher } from '../../base/feedback/feedback-action-dispatcher';
|
|
@@ -33,7 +44,7 @@ import {
|
|
|
33
44
|
ViewportLineType
|
|
34
45
|
} from './helper-line-feedback';
|
|
35
46
|
import { IHelperLineManager } from './helper-line-manager';
|
|
36
|
-
import { Direction, HelperLineType } from './model';
|
|
47
|
+
import { Direction, HelperLine, HelperLineType, isHelperLine } from './model';
|
|
37
48
|
|
|
38
49
|
export interface IHelperLineOptions {
|
|
39
50
|
/**
|
|
@@ -158,4 +169,28 @@ export class HelperLineManager implements IActionHandler, ISelectionListener, IH
|
|
|
158
169
|
? this.options.minimumMoveDelta.x
|
|
159
170
|
: this.options.minimumMoveDelta.y;
|
|
160
171
|
}
|
|
172
|
+
|
|
173
|
+
getMinimumMoveVector(element: GModelElement, isSnap: boolean, directions: Direction[]): Vector | undefined {
|
|
174
|
+
if (!isSnap) {
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const helperLines = element.root.children.filter(child => isHelperLine(child)) as HelperLine[];
|
|
179
|
+
if (helperLines.length === 0) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const minimum: Writable<Vector> = { ...Vector.ZERO };
|
|
184
|
+
if (directions.includes(Direction.Left) && helperLines.some(line => line.isLeft || line.isCenter)) {
|
|
185
|
+
minimum.x = this.getMinimumMoveDelta(element, isSnap, Direction.Left);
|
|
186
|
+
} else if (directions.includes(Direction.Right) && helperLines.some(line => line.isRight || line.isCenter)) {
|
|
187
|
+
minimum.x = this.getMinimumMoveDelta(element, isSnap, Direction.Right);
|
|
188
|
+
}
|
|
189
|
+
if (directions.includes(Direction.Up) && helperLines.some(line => line.isTop || line.isMiddle)) {
|
|
190
|
+
minimum.y = this.getMinimumMoveDelta(element, isSnap, Direction.Up);
|
|
191
|
+
} else if (directions.includes(Direction.Down) && helperLines.some(line => line.isBottom || line.isMiddle)) {
|
|
192
|
+
minimum.y = this.getMinimumMoveDelta(element, isSnap, Direction.Down);
|
|
193
|
+
}
|
|
194
|
+
return Vector.isZero(minimum) ? undefined : minimum;
|
|
195
|
+
}
|
|
161
196
|
}
|
|
@@ -13,16 +13,25 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { GModelElement } from '@eclipse-glsp/sprotty';
|
|
16
|
+
import { GModelElement, Vector } from '@eclipse-glsp/sprotty';
|
|
17
17
|
import { Direction } from './model';
|
|
18
18
|
|
|
19
19
|
export interface IHelperLineManager {
|
|
20
20
|
/**
|
|
21
|
-
* Calculates the minimum move delta that is necessary to break through a helper line.
|
|
21
|
+
* Calculates the minimum move delta on one axis that is necessary to break through a helper line.
|
|
22
22
|
*
|
|
23
23
|
* @param element element that is being moved
|
|
24
24
|
* @param isSnap whether snapping is active or not
|
|
25
25
|
* @param direction direction in which the target element is moving
|
|
26
26
|
*/
|
|
27
27
|
getMinimumMoveDelta(element: GModelElement, isSnap: boolean, direction: Direction): number;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Calculates the minimum move vector that is necessary to break through a helper line.
|
|
31
|
+
*
|
|
32
|
+
* @param element element that is being moved
|
|
33
|
+
* @param isSnap whether snapping is active or not
|
|
34
|
+
* @param directions directions in which the target element is moving
|
|
35
|
+
*/
|
|
36
|
+
getMinimumMoveVector(element: GModelElement, isSnap: boolean, directions: Direction[]): Vector | undefined;
|
|
28
37
|
}
|
|
@@ -41,6 +41,13 @@ export abstract class GLSPAbstractEdgeRouter extends AbstractEdgeRouter {
|
|
|
41
41
|
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
|
|
42
42
|
return Point.isValid(anchor) ? anchor : refPoint;
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
override cleanupRoutingPoints(edge: GRoutableElement, routingPoints: Point[], updateHandles: boolean, addRoutingPoints: boolean): void {
|
|
46
|
+
// sometimes it might happen that the source or target has the bounds not properly set when using the feedback edge
|
|
47
|
+
if (ensureBounds(edge.source) && ensureBounds(edge.target)) {
|
|
48
|
+
super.cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
@injectable()
|
|
@@ -56,6 +63,13 @@ export class GLSPPolylineEdgeRouter extends PolylineEdgeRouter {
|
|
|
56
63
|
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
|
|
57
64
|
return Point.isValid(anchor) ? anchor : refPoint;
|
|
58
65
|
}
|
|
66
|
+
|
|
67
|
+
override cleanupRoutingPoints(edge: GRoutableElement, routingPoints: Point[], updateHandles: boolean, addRoutingPoints: boolean): void {
|
|
68
|
+
// sometimes it might happen that the source or target has the bounds not properly set when using the feedback edge
|
|
69
|
+
if (ensureBounds(edge.source) && ensureBounds(edge.target)) {
|
|
70
|
+
super.cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
@injectable()
|
|
@@ -111,6 +125,13 @@ export class GLSPManhattanEdgeRouter extends ManhattanEdgeRouter {
|
|
|
111
125
|
}
|
|
112
126
|
});
|
|
113
127
|
}
|
|
128
|
+
|
|
129
|
+
override cleanupRoutingPoints(edge: GRoutableElement, routingPoints: Point[], updateHandles: boolean, addRoutingPoints: boolean): void {
|
|
130
|
+
// sometimes it might happen that the source or target has the bounds not properly set when using the feedback edge
|
|
131
|
+
if (ensureBounds(edge.source) && ensureBounds(edge.target)) {
|
|
132
|
+
super.cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
114
135
|
}
|
|
115
136
|
|
|
116
137
|
@injectable()
|
|
@@ -126,4 +147,25 @@ export class GLSPBezierEdgeRouter extends BezierEdgeRouter {
|
|
|
126
147
|
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
|
|
127
148
|
return Point.isValid(anchor) ? anchor : refPoint;
|
|
128
149
|
}
|
|
150
|
+
|
|
151
|
+
override cleanupRoutingPoints(edge: GRoutableElement, routingPoints: Point[], updateHandles: boolean, addRoutingPoints: boolean): void {
|
|
152
|
+
// sometimes it might happen that the source or target has the bounds not properly set when using the feedback edge
|
|
153
|
+
if (ensureBounds(edge.source) && ensureBounds(edge.target)) {
|
|
154
|
+
super.cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function ensureBounds(element?: GConnectableElement): boolean {
|
|
160
|
+
if (!element) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (element.bounds) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
if (element.position && element.size) {
|
|
167
|
+
element.bounds = { ...element.position, ...element.size };
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
129
171
|
}
|
|
@@ -13,17 +13,23 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { Action, BringToFrontAction, GModelElement, SelectAction, SelectMouseListener } from '@eclipse-glsp/sprotty';
|
|
16
|
+
import { Action, BringToFrontAction, GModelElement, SelectAction, SelectMouseListener, TYPES } from '@eclipse-glsp/sprotty';
|
|
17
|
+
import { inject, injectable, optional } from 'inversify';
|
|
17
18
|
import { Ranked } from '../../base/ranked';
|
|
18
19
|
import { SelectableElement } from '../../utils';
|
|
20
|
+
import { SResizeHandle } from '../change-bounds';
|
|
21
|
+
import { ChangeBoundsManager } from '../tools';
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* Ranked select mouse listener that is executed before default mouse listeners when using the RankedMouseTool.
|
|
22
25
|
* This ensures that default mouse listeners are working on a model that has selection changes already applied.
|
|
23
26
|
*/
|
|
27
|
+
@injectable()
|
|
24
28
|
export class RankedSelectMouseListener extends SelectMouseListener implements Ranked {
|
|
25
29
|
rank: number = Ranked.DEFAULT_RANK - 100; /* we want to be executed before all default mouse listeners */
|
|
26
30
|
|
|
31
|
+
@inject(TYPES.IChangeBoundsManager) @optional() readonly changeBoundsManager?: ChangeBoundsManager;
|
|
32
|
+
|
|
27
33
|
protected override handleSelectTarget(
|
|
28
34
|
selectableTarget: SelectableElement,
|
|
29
35
|
deselectedElements: GModelElement[],
|
|
@@ -52,4 +58,12 @@ export class RankedSelectMouseListener extends SelectMouseListener implements Ra
|
|
|
52
58
|
result.push(SelectAction.create({ selectedElementsIDs: [], deselectedElementsIDs: deselectedElements.map(e => e.id) }));
|
|
53
59
|
return result;
|
|
54
60
|
}
|
|
61
|
+
|
|
62
|
+
protected override handleButton(target: GModelElement, event: MouseEvent): (Action | Promise<Action>)[] | undefined {
|
|
63
|
+
if (target instanceof SResizeHandle && this.changeBoundsManager?.useSymmetricResize(event)) {
|
|
64
|
+
// avoid de-selecting elements when resizing with a modifier key
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
return super.handleButton(target, event);
|
|
68
|
+
}
|
|
55
69
|
}
|
|
@@ -23,11 +23,41 @@ import { EnableToolsAction, Tool } from '../../base/tool-manager/tool';
|
|
|
23
23
|
import { GLSPKeyTool } from '../../base/view/key-tool';
|
|
24
24
|
import { GLSPMouseTool } from '../../base/view/mouse-tool';
|
|
25
25
|
|
|
26
|
+
export interface FeedbackAwareTool extends Tool {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new feedback emitter helper object. While anything can serve as a feedback emitter,
|
|
29
|
+
* this method ensures that the emitter is stable and does not change between model updates.
|
|
30
|
+
*/
|
|
31
|
+
createFeedbackEmitter(): FeedbackEmitter;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Registers `actions` to be sent out as feedback, i.e., changes that are re-established whenever the `GModelRoot`
|
|
35
|
+
* has been set or updated.
|
|
36
|
+
*
|
|
37
|
+
* @param feedbackActions the actions to be sent out.
|
|
38
|
+
* @param feedbackEmitter the emitter sending out feedback actions (this tool by default).
|
|
39
|
+
* @param cleanupActions the actions to be sent out when the feedback is de-registered through the returned Disposable.
|
|
40
|
+
* @returns A 'Disposable' that de-registers the feedback and cleans up any pending feedback with the given `cleanupActions`.
|
|
41
|
+
* @deprecated It is recommended to create a {@link createFeedbackEmitter dedicated emitter} per feedback instead of using the tool.
|
|
42
|
+
*/
|
|
43
|
+
registerFeedback(feedbackActions: Action[], feedbackEmitter?: IFeedbackEmitter, cleanupActions?: MaybeActions): Disposable;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* De-registers all feedback from the given `feedbackEmitter` (this tool by default) and cleans up any pending feedback with the
|
|
47
|
+
* given `cleanupActions`.
|
|
48
|
+
*
|
|
49
|
+
* @param feedbackEmitter the emitter to be deregistered (this tool by default).
|
|
50
|
+
* @param cleanupActions the actions to be dispatched right after the deregistration to clean up any pending feedback.
|
|
51
|
+
* @deprecated It is recommended to create a {@link createFeedbackEmitter dedicated emitter} per feedback and dispose it like that.
|
|
52
|
+
*/
|
|
53
|
+
deregisterFeedback(feedbackEmitter?: IFeedbackEmitter, cleanupActions?: MaybeActions): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
26
56
|
/**
|
|
27
57
|
* A reusable base implementation for edit {@link Tool}s.
|
|
28
58
|
*/
|
|
29
59
|
@injectable()
|
|
30
|
-
export abstract class BaseEditTool implements
|
|
60
|
+
export abstract class BaseEditTool implements FeedbackAwareTool {
|
|
31
61
|
@inject(TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher;
|
|
32
62
|
@inject(TYPES.IActionDispatcher) protected actionDispatcher: GLSPActionDispatcher;
|
|
33
63
|
@inject(GLSPMouseTool) protected mouseTool: GLSPMouseTool;
|
|
@@ -56,28 +86,10 @@ export abstract class BaseEditTool implements Tool {
|
|
|
56
86
|
return this.feedbackDispatcher.createEmitter();
|
|
57
87
|
}
|
|
58
88
|
|
|
59
|
-
/**
|
|
60
|
-
* Registers `actions` to be sent out as feedback, i.e., changes that are re-established whenever the `GModelRoot`
|
|
61
|
-
* has been set or updated.
|
|
62
|
-
*
|
|
63
|
-
* @param feedbackActions the actions to be sent out.
|
|
64
|
-
* @param feedbackEmitter the emitter sending out feedback actions (this tool by default).
|
|
65
|
-
* @param cleanupActions the actions to be sent out when the feedback is de-registered through the returned Disposable.
|
|
66
|
-
* @returns A 'Disposable' that de-registers the feedback and cleans up any pending feedback with the given `cleanupActions`.
|
|
67
|
-
* @deprecated It is recommended to create a {@link createFeedbackEmitter dedicated emitter} per feedback instead of using the tool.
|
|
68
|
-
*/
|
|
69
89
|
registerFeedback(feedbackActions: Action[], feedbackEmitter: IFeedbackEmitter = this, cleanupActions?: MaybeActions): Disposable {
|
|
70
90
|
return this.feedbackDispatcher.registerFeedback(feedbackEmitter, feedbackActions, cleanupActions);
|
|
71
91
|
}
|
|
72
92
|
|
|
73
|
-
/**
|
|
74
|
-
* De-registers all feedback from the given `feedbackEmitter` (this tool by default) and cleans up any pending feedback with the
|
|
75
|
-
* given `cleanupActions`.
|
|
76
|
-
*
|
|
77
|
-
* @param feedbackEmitter the emitter to be deregistered (this tool by default).
|
|
78
|
-
* @param cleanupActions the actions to be dispatched right after the deregistration to clean up any pending feedback.
|
|
79
|
-
* @deprecated It is recommended to create a {@link createFeedbackEmitter dedicated emitter} per feedback and dispose it like that.
|
|
80
|
-
*/
|
|
81
93
|
deregisterFeedback(feedbackEmitter: IFeedbackEmitter = this, cleanupActions?: MaybeActions): void {
|
|
82
94
|
this.feedbackDispatcher.deregisterFeedback(feedbackEmitter, cleanupActions);
|
|
83
95
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2024 Axon Ivy AG and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
Dimension,
|
|
19
|
+
GModelElement,
|
|
20
|
+
ISnapper,
|
|
21
|
+
KeyboardModifier,
|
|
22
|
+
MousePositionTracker,
|
|
23
|
+
Movement,
|
|
24
|
+
Point,
|
|
25
|
+
TYPES,
|
|
26
|
+
Vector,
|
|
27
|
+
isBoundsAware,
|
|
28
|
+
isLocateable
|
|
29
|
+
} from '@eclipse-glsp/sprotty';
|
|
30
|
+
import { inject, injectable, optional } from 'inversify';
|
|
31
|
+
import { FeedbackEmitter } from '../../../base';
|
|
32
|
+
import { isValidMove, minDimensions } from '../../../utils';
|
|
33
|
+
import { LayoutAware } from '../../bounds/layout-data';
|
|
34
|
+
import {
|
|
35
|
+
IMovementRestrictor,
|
|
36
|
+
ResizeHandleLocation,
|
|
37
|
+
movementRestrictionFeedback,
|
|
38
|
+
removeMovementRestrictionFeedback
|
|
39
|
+
} from '../../change-bounds';
|
|
40
|
+
import { IHelperLineManager } from '../../helper-lines';
|
|
41
|
+
import { ChangeBoundsTracker, TrackedElementMove } from './change-bounds-tracker';
|
|
42
|
+
|
|
43
|
+
export const CSS_RESIZE_MODE = 'resize-mode';
|
|
44
|
+
|
|
45
|
+
@injectable()
|
|
46
|
+
export class ChangeBoundsManager {
|
|
47
|
+
constructor(
|
|
48
|
+
@inject(MousePositionTracker) readonly positionTracker: MousePositionTracker,
|
|
49
|
+
@optional() @inject(TYPES.IMovementRestrictor) readonly movementRestrictor?: IMovementRestrictor,
|
|
50
|
+
@optional() @inject(TYPES.ISnapper) readonly snapper?: ISnapper,
|
|
51
|
+
@optional() @inject(TYPES.IHelperLineManager) readonly helperLineManager?: IHelperLineManager
|
|
52
|
+
) {}
|
|
53
|
+
|
|
54
|
+
unsnapModifier(): KeyboardModifier | undefined {
|
|
55
|
+
return 'shift';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
usePositionSnap(arg: MouseEvent | KeyboardEvent | any): boolean {
|
|
59
|
+
return typeof arg === 'boolean' ? arg : !(arg as MouseEvent | KeyboardEvent).shiftKey;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
snapPosition(element: GModelElement, position: Point): Point {
|
|
63
|
+
return this.snapper?.snap(position, element) ?? position;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
isValid(element: GModelElement): boolean {
|
|
67
|
+
return this.hasValidPosition(element) && this.hasValidSize(element);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
hasValidPosition(element: GModelElement, position?: Point): boolean {
|
|
71
|
+
return !isLocateable(element) || isValidMove(element, position ?? element.position, this.movementRestrictor);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
hasValidSize(element: GModelElement, size?: Dimension): boolean {
|
|
75
|
+
if (!isBoundsAware(element)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
const dimension: Dimension = size ?? element.bounds;
|
|
79
|
+
const minimum = this.getMinimumSize(element);
|
|
80
|
+
if (dimension.width < minimum.width || dimension.height < minimum.height) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
getMinimumSize(element: GModelElement): Dimension {
|
|
87
|
+
if (!isBoundsAware(element)) {
|
|
88
|
+
return Dimension.EMPTY;
|
|
89
|
+
}
|
|
90
|
+
const definedMinimum = minDimensions(element);
|
|
91
|
+
const computedMinimum = LayoutAware.getComputedDimensions(element);
|
|
92
|
+
return computedMinimum
|
|
93
|
+
? {
|
|
94
|
+
width: Math.max(definedMinimum.width, computedMinimum.width),
|
|
95
|
+
height: Math.max(definedMinimum.height, computedMinimum.height)
|
|
96
|
+
}
|
|
97
|
+
: definedMinimum;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
useMovementRestriction(arg: MouseEvent | KeyboardEvent | any): boolean {
|
|
101
|
+
return this.usePositionSnap(arg);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
restrictMovement(element: GModelElement, movement: Movement): Movement {
|
|
105
|
+
const minimumMovement = this.helperLineManager?.getMinimumMoveVector(element, true, movement.direction);
|
|
106
|
+
if (!minimumMovement) {
|
|
107
|
+
return movement;
|
|
108
|
+
}
|
|
109
|
+
// minimum is given in absolute coordinates
|
|
110
|
+
// if minimum is not reached, reset to original position for that coordinate
|
|
111
|
+
const absVector = Vector.abs(movement.vector);
|
|
112
|
+
const targetPosition: Point = {
|
|
113
|
+
x: absVector.x < minimumMovement.x ? movement.from.x : movement.to.x,
|
|
114
|
+
y: absVector.y < minimumMovement.y ? movement.from.y : movement.to.y
|
|
115
|
+
};
|
|
116
|
+
return Point.move(movement.from, targetPosition);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
addRestrictionFeedback(feedback: FeedbackEmitter, move: TrackedElementMove): FeedbackEmitter {
|
|
120
|
+
if (this.movementRestrictor) {
|
|
121
|
+
feedback.add(
|
|
122
|
+
movementRestrictionFeedback(move.element, this.movementRestrictor!, move.valid),
|
|
123
|
+
removeMovementRestrictionFeedback(move.element, this.movementRestrictor!)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return feedback;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
defaultResizeLocations(): ResizeHandleLocation[] {
|
|
130
|
+
return [
|
|
131
|
+
ResizeHandleLocation.TopLeft,
|
|
132
|
+
ResizeHandleLocation.TopRight,
|
|
133
|
+
ResizeHandleLocation.BottomRight,
|
|
134
|
+
ResizeHandleLocation.BottomLeft
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
useSymmetricResize(arg: MouseEvent | KeyboardEvent | any): boolean {
|
|
139
|
+
return typeof arg === 'boolean' ? arg : (arg as MouseEvent | KeyboardEvent).ctrlKey;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
createTracker(): ChangeBoundsTracker {
|
|
143
|
+
return new ChangeBoundsTracker(this);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -19,12 +19,14 @@ import { inject, injectable } from 'inversify';
|
|
|
19
19
|
import { FeedbackCommand } from '../../../base/feedback/feedback-command';
|
|
20
20
|
import { OptionalAction } from '../../../base/model/glsp-model-source';
|
|
21
21
|
import { forEachElement } from '../../../utils/gmodel-util';
|
|
22
|
-
import { addResizeHandles, isResizable, removeResizeHandles } from '../../change-bounds/model';
|
|
22
|
+
import { ResizeHandleLocation, addResizeHandles, isResizable, removeResizeHandles } from '../../change-bounds/model';
|
|
23
|
+
import { ChangeBoundsManager } from './change-bounds-manager';
|
|
23
24
|
|
|
24
25
|
export interface ShowChangeBoundsToolResizeFeedbackAction extends Action {
|
|
25
26
|
kind: typeof ShowChangeBoundsToolResizeFeedbackAction.KIND;
|
|
26
27
|
|
|
27
28
|
elementId: string;
|
|
29
|
+
resizeLocations?: ResizeHandleLocation[];
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export namespace ShowChangeBoundsToolResizeFeedbackAction {
|
|
@@ -34,10 +36,16 @@ export namespace ShowChangeBoundsToolResizeFeedbackAction {
|
|
|
34
36
|
return Action.hasKind(object, KIND) && hasStringProp(object, 'elementId');
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
/** @deprecated Use the create method with the options object parameter instead and set the 'elementId' parameter. */
|
|
40
|
+
export function create(elementId: string): ShowChangeBoundsToolResizeFeedbackAction;
|
|
41
|
+
export function create(options: Omit<ShowChangeBoundsToolResizeFeedbackAction, 'kind'>): ShowChangeBoundsToolResizeFeedbackAction;
|
|
42
|
+
export function create(
|
|
43
|
+
options: Omit<ShowChangeBoundsToolResizeFeedbackAction, 'kind'> | string
|
|
44
|
+
): ShowChangeBoundsToolResizeFeedbackAction {
|
|
45
|
+
const opts = typeof options === 'string' ? { elementId: options } : options;
|
|
38
46
|
return {
|
|
39
47
|
kind: KIND,
|
|
40
|
-
|
|
48
|
+
...opts
|
|
41
49
|
};
|
|
42
50
|
}
|
|
43
51
|
}
|
|
@@ -63,15 +71,18 @@ export class ShowChangeBoundsToolResizeFeedbackCommand extends FeedbackCommand {
|
|
|
63
71
|
static readonly KIND = ShowChangeBoundsToolResizeFeedbackAction.KIND;
|
|
64
72
|
|
|
65
73
|
@inject(TYPES.Action) protected action: ShowChangeBoundsToolResizeFeedbackAction;
|
|
74
|
+
@inject(TYPES.IChangeBoundsManager) protected changeBoundsManager: ChangeBoundsManager;
|
|
66
75
|
|
|
67
76
|
execute(context: CommandExecutionContext): CommandReturn {
|
|
68
77
|
const index = context.root.index;
|
|
69
78
|
|
|
70
79
|
forEachElement(index, isResizable, element => element.id !== this.action.elementId && removeResizeHandles(element));
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
if (this.action.elementId) {
|
|
82
|
+
const resizeElement = index.getById(this.action.elementId);
|
|
83
|
+
if (resizeElement && isResizable(resizeElement)) {
|
|
84
|
+
addResizeHandles(resizeElement, this.action.resizeLocations ?? this.changeBoundsManager.defaultResizeLocations());
|
|
85
|
+
}
|
|
75
86
|
}
|
|
76
87
|
return context.root;
|
|
77
88
|
}
|
|
@@ -16,12 +16,14 @@
|
|
|
16
16
|
import { FeatureModule, TYPES, bindAsService, configureCommand, configureView } from '@eclipse-glsp/sprotty';
|
|
17
17
|
import '../../../../css/change-bounds.css';
|
|
18
18
|
import { SResizeHandle } from '../../change-bounds/model';
|
|
19
|
+
import { ChangeBoundsManager } from './change-bounds-manager';
|
|
19
20
|
import { ChangeBoundsTool } from './change-bounds-tool';
|
|
20
21
|
import { HideChangeBoundsToolResizeFeedbackCommand, ShowChangeBoundsToolResizeFeedbackCommand } from './change-bounds-tool-feedback';
|
|
21
22
|
import { SResizeHandleView } from './view';
|
|
22
23
|
|
|
23
24
|
export const changeBoundsToolModule = new FeatureModule((bind, unbind, isBound, rebind) => {
|
|
24
25
|
const context = { bind, unbind, isBound, rebind };
|
|
26
|
+
bindAsService(context, TYPES.IChangeBoundsManager, ChangeBoundsManager);
|
|
25
27
|
bindAsService(context, TYPES.IDefaultTool, ChangeBoundsTool);
|
|
26
28
|
configureCommand(context, ShowChangeBoundsToolResizeFeedbackCommand);
|
|
27
29
|
configureCommand(context, HideChangeBoundsToolResizeFeedbackCommand);
|