@eclipse-glsp/client 0.9.0-next.da0ffb79 → 0.9.0-next.e0116720
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 +642 -277
- package/lib/base/types.d.ts +1 -0
- package/lib/base/types.d.ts.map +1 -1
- package/lib/base/types.js +2 -1
- package/lib/base/types.js.map +1 -1
- package/lib/features/layout/di.config.d.ts +0 -4
- package/lib/features/layout/di.config.d.ts.map +1 -1
- package/lib/features/layout/di.config.js +1 -37
- package/lib/features/layout/di.config.js.map +1 -1
- package/lib/features/tools/marquee-behavior.d.ts +42 -0
- package/lib/features/tools/marquee-behavior.d.ts.map +1 -0
- package/lib/features/tools/marquee-behavior.js +128 -0
- package/lib/features/tools/marquee-behavior.js.map +1 -0
- package/lib/features/tools/marquee-behavior.spec.d.ts +17 -0
- package/lib/features/tools/marquee-behavior.spec.d.ts.map +1 -0
- package/lib/features/tools/marquee-behavior.spec.js +165 -0
- package/lib/features/tools/marquee-behavior.spec.js.map +1 -0
- package/lib/features/tools/marquee-mouse-tool.d.ts +9 -14
- package/lib/features/tools/marquee-mouse-tool.d.ts.map +1 -1
- package/lib/features/tools/marquee-mouse-tool.js +30 -119
- package/lib/features/tools/marquee-mouse-tool.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/src/base/types.ts +2 -1
- package/src/features/layout/di.config.ts +3 -25
- package/src/features/tools/marquee-behavior.spec.ts +175 -0
- package/src/features/tools/marquee-behavior.ts +158 -0
- package/src/features/tools/marquee-mouse-tool.ts +46 -144
- package/src/index.ts +1 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2021 EclipseSource 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 { Bounds, Point } from '@eclipse-glsp/protocol';
|
|
18
|
+
import { PointToPointLine } from 'sprotty';
|
|
19
|
+
import { DrawMarqueeAction } from '../tool-feedback/marquee-tool-feedback';
|
|
20
|
+
|
|
21
|
+
export interface IMarqueeBehavior {
|
|
22
|
+
readonly entireElement: boolean;
|
|
23
|
+
readonly entireEdge: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class MarqueeUtil {
|
|
27
|
+
protected startPoint: Point;
|
|
28
|
+
protected currentPoint: Point;
|
|
29
|
+
protected marqueeBehavior: IMarqueeBehavior;
|
|
30
|
+
|
|
31
|
+
constructor(marqueeBehavior?: IMarqueeBehavior) {
|
|
32
|
+
if (marqueeBehavior) {
|
|
33
|
+
this.marqueeBehavior = marqueeBehavior;
|
|
34
|
+
} else {
|
|
35
|
+
this.marqueeBehavior = { entireElement: false, entireEdge: false };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
updateStartPoint(position: Point): void {
|
|
40
|
+
this.startPoint = position;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updateCurrentPoint(position: Point): void {
|
|
44
|
+
this.currentPoint = position;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
drawMarqueeAction(): DrawMarqueeAction {
|
|
48
|
+
return new DrawMarqueeAction(this.startPoint, this.currentPoint);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
isEdgePathMarked(path: string | null): boolean {
|
|
52
|
+
if (!path) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const points = path
|
|
56
|
+
.split(/M|L/)
|
|
57
|
+
.filter(p => p)
|
|
58
|
+
.map(p => {
|
|
59
|
+
const coord = p.split(',');
|
|
60
|
+
return { x: parseInt(coord[0], 10), y: parseInt(coord[1], 10) };
|
|
61
|
+
});
|
|
62
|
+
return this.isEdgeMarked(points);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isEdgeMarked(points: Point[]): boolean {
|
|
66
|
+
return this.marqueeBehavior.entireEdge ? this.isEntireEdgeMarked(points) : this.isPartOfEdgeMarked(points);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
isNodeMarked(elementBounds: Bounds): boolean {
|
|
70
|
+
const horizontallyIn =
|
|
71
|
+
this.startPoint.x < this.currentPoint.x
|
|
72
|
+
? this.isElementBetweenXAxis(elementBounds, this.startPoint.x, this.currentPoint.x)
|
|
73
|
+
: this.isElementBetweenXAxis(elementBounds, this.currentPoint.x, this.startPoint.x);
|
|
74
|
+
const verticallyIn =
|
|
75
|
+
this.startPoint.y < this.currentPoint.y
|
|
76
|
+
? this.isElementBetweenYAxis(elementBounds, this.startPoint.y, this.currentPoint.y)
|
|
77
|
+
: this.isElementBetweenYAxis(elementBounds, this.currentPoint.y, this.startPoint.y);
|
|
78
|
+
return horizontallyIn && verticallyIn;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private isEntireEdgeMarked(points: Point[]): boolean {
|
|
82
|
+
for (let i = 0; i < points.length; i++) {
|
|
83
|
+
if (!this.pointInRect(points[i])) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private isPartOfEdgeMarked(points: Point[]): boolean {
|
|
91
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
92
|
+
if (this.isLineMarked(points[i], points[i + 1])) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private isLineMarked(point1: Point, point2: Point): boolean {
|
|
100
|
+
const line = new PointToPointLine(point1, point2);
|
|
101
|
+
return (
|
|
102
|
+
this.pointInRect(point1) ||
|
|
103
|
+
this.pointInRect(point2) ||
|
|
104
|
+
this.lineIntersect(line, this.startPoint, { x: this.startPoint.x, y: this.currentPoint.y }) ||
|
|
105
|
+
this.lineIntersect(line, this.startPoint, { x: this.currentPoint.x, y: this.startPoint.y }) ||
|
|
106
|
+
this.lineIntersect(line, { x: this.currentPoint.x, y: this.startPoint.y }, this.currentPoint) ||
|
|
107
|
+
this.lineIntersect(line, { x: this.startPoint.x, y: this.currentPoint.y }, this.currentPoint)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private lineIntersect(line: PointToPointLine, p1: Point, p2: Point): boolean {
|
|
112
|
+
return line.intersection(new PointToPointLine(p1, p2)) !== undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private pointInRect(point: Point): boolean {
|
|
116
|
+
const boolX =
|
|
117
|
+
this.startPoint.x <= this.currentPoint.x
|
|
118
|
+
? this.isBetween(point.x, this.startPoint.x, this.currentPoint.x)
|
|
119
|
+
: this.isBetween(point.x, this.currentPoint.x, this.startPoint.x);
|
|
120
|
+
const boolY =
|
|
121
|
+
this.startPoint.y <= this.currentPoint.y
|
|
122
|
+
? this.isBetween(point.y, this.startPoint.y, this.currentPoint.y)
|
|
123
|
+
: this.isBetween(point.y, this.currentPoint.y, this.startPoint.y);
|
|
124
|
+
return boolX && boolY;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private isElementBetweenXAxis(elementBounds: Bounds, marqueeLeft: number, marqueeRight: number): boolean {
|
|
128
|
+
const leftEdge = this.isBetween(elementBounds.x, marqueeLeft, marqueeRight);
|
|
129
|
+
const rightEdge = this.isBetween(elementBounds.x + elementBounds.width, marqueeLeft, marqueeRight);
|
|
130
|
+
if (this.marqueeBehavior.entireElement) {
|
|
131
|
+
return leftEdge && rightEdge;
|
|
132
|
+
}
|
|
133
|
+
return (
|
|
134
|
+
leftEdge ||
|
|
135
|
+
rightEdge ||
|
|
136
|
+
this.isBetween(marqueeLeft, elementBounds.x, elementBounds.x + elementBounds.width) ||
|
|
137
|
+
this.isBetween(marqueeRight, elementBounds.x, elementBounds.x + elementBounds.width)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private isElementBetweenYAxis(elementBounds: Bounds, marqueeTop: number, marqueeBottom: number): boolean {
|
|
142
|
+
const topEdge = this.isBetween(elementBounds.y, marqueeTop, marqueeBottom);
|
|
143
|
+
const bottomEdge = this.isBetween(elementBounds.y + elementBounds.height, marqueeTop, marqueeBottom);
|
|
144
|
+
if (this.marqueeBehavior.entireElement) {
|
|
145
|
+
return topEdge && bottomEdge;
|
|
146
|
+
}
|
|
147
|
+
return (
|
|
148
|
+
topEdge ||
|
|
149
|
+
bottomEdge ||
|
|
150
|
+
this.isBetween(marqueeTop, elementBounds.y, elementBounds.y + elementBounds.height) ||
|
|
151
|
+
this.isBetween(marqueeBottom, elementBounds.y, elementBounds.y + elementBounds.height)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private isBetween(x: number, lower: number, upper: number): boolean {
|
|
156
|
+
return lower <= x && x <= upper;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -13,21 +13,35 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { Action,
|
|
17
|
-
import { inject, injectable } from 'inversify';
|
|
18
|
-
import {
|
|
16
|
+
import { Action, SelectAction } from '@eclipse-glsp/protocol';
|
|
17
|
+
import { inject, injectable, optional } from 'inversify';
|
|
18
|
+
import {
|
|
19
|
+
BoundsAware,
|
|
20
|
+
EnableDefaultToolsAction,
|
|
21
|
+
isSelectable,
|
|
22
|
+
isSelected,
|
|
23
|
+
KeyListener,
|
|
24
|
+
SEdge,
|
|
25
|
+
SModelElement,
|
|
26
|
+
SModelRoot,
|
|
27
|
+
SNode,
|
|
28
|
+
TYPES
|
|
29
|
+
} from 'sprotty';
|
|
19
30
|
import { DOMHelper } from 'sprotty/lib/base/views/dom-helper';
|
|
31
|
+
import { GLSP_TYPES } from '../../base/types';
|
|
20
32
|
import { DragAwareMouseListener } from '../../base/drag-aware-mouse-listener';
|
|
21
33
|
import { getAbsolutePosition, toAbsoluteBounds } from '../../utils/viewpoint-util';
|
|
22
34
|
import { CursorCSS, cursorFeedbackAction } from '../tool-feedback/css-feedback';
|
|
23
|
-
import {
|
|
24
|
-
import { BaseGLSPTool } from '
|
|
35
|
+
import { RemoveMarqueeAction } from '../tool-feedback/marquee-tool-feedback';
|
|
36
|
+
import { BaseGLSPTool } from './base-glsp-tool';
|
|
37
|
+
import { IMarqueeBehavior, MarqueeUtil } from './marquee-behavior';
|
|
25
38
|
|
|
26
39
|
@injectable()
|
|
27
40
|
export class MarqueeMouseTool extends BaseGLSPTool {
|
|
28
41
|
static ID = 'glsp.marquee-mouse-tool';
|
|
29
42
|
|
|
30
43
|
@inject(TYPES.DOMHelper) protected domHelper: DOMHelper;
|
|
44
|
+
@inject(GLSP_TYPES.IMarqueeBehavior) @optional() protected marqueeBehavior: IMarqueeBehavior;
|
|
31
45
|
|
|
32
46
|
protected marqueeMouseListener: MarqueeMouseListener;
|
|
33
47
|
protected shiftKeyListener: ShiftKeyListener = new ShiftKeyListener();
|
|
@@ -37,7 +51,7 @@ export class MarqueeMouseTool extends BaseGLSPTool {
|
|
|
37
51
|
}
|
|
38
52
|
|
|
39
53
|
enable(): void {
|
|
40
|
-
this.marqueeMouseListener = new MarqueeMouseListener(this.domHelper);
|
|
54
|
+
this.marqueeMouseListener = new MarqueeMouseListener(this.domHelper, this.editorContext.modelRoot, this.marqueeBehavior);
|
|
41
55
|
this.mouseTool.register(this.marqueeMouseListener);
|
|
42
56
|
this.keyTool.register(this.shiftKeyListener);
|
|
43
57
|
this.dispatchFeedback([cursorFeedbackAction(CursorCSS.MARQUEE)]);
|
|
@@ -50,26 +64,38 @@ export class MarqueeMouseTool extends BaseGLSPTool {
|
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
|
|
53
|
-
@injectable()
|
|
54
67
|
export class MarqueeMouseListener extends DragAwareMouseListener {
|
|
55
|
-
protected startPoint: Point;
|
|
56
|
-
|
|
57
|
-
protected currentPoint: Point;
|
|
58
|
-
|
|
59
68
|
protected domHelper: DOMHelper;
|
|
60
|
-
|
|
69
|
+
protected marqueeUtil: MarqueeUtil;
|
|
70
|
+
protected nodes: (SModelElement & BoundsAware)[];
|
|
71
|
+
protected edges: SVGGElement[];
|
|
61
72
|
protected previouslySelected: string[];
|
|
62
|
-
|
|
63
73
|
protected isActive = false;
|
|
64
74
|
|
|
65
|
-
constructor(domHelper: DOMHelper) {
|
|
75
|
+
constructor(domHelper: DOMHelper, root: SModelRoot, marqueeBehavior: IMarqueeBehavior | undefined) {
|
|
66
76
|
super();
|
|
67
77
|
this.domHelper = domHelper;
|
|
78
|
+
this.marqueeUtil = new MarqueeUtil(marqueeBehavior);
|
|
79
|
+
this.nodes = Array.from(
|
|
80
|
+
root.index
|
|
81
|
+
.all()
|
|
82
|
+
.map(e => e as SModelElement & BoundsAware)
|
|
83
|
+
.filter(e => isSelectable(e))
|
|
84
|
+
.filter(e => e instanceof SNode)
|
|
85
|
+
);
|
|
86
|
+
const sEdges = Array.from(
|
|
87
|
+
root.index
|
|
88
|
+
.all()
|
|
89
|
+
.filter(e => e instanceof SEdge)
|
|
90
|
+
.filter(e => isSelectable(e))
|
|
91
|
+
.map(e => e.id)
|
|
92
|
+
);
|
|
93
|
+
this.edges = Array.from(document.querySelectorAll('g')).filter(e => sEdges.includes(this.domHelper.findSModelIdByDOMElement(e)));
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
mouseDown(target: SModelElement, event: MouseEvent): Action[] {
|
|
71
97
|
this.isActive = true;
|
|
72
|
-
this.
|
|
98
|
+
this.marqueeUtil.updateStartPoint(getAbsolutePosition(target, event));
|
|
73
99
|
if (event.ctrlKey) {
|
|
74
100
|
this.previouslySelected = Array.from(
|
|
75
101
|
target.root.index
|
|
@@ -83,23 +109,15 @@ export class MarqueeMouseListener extends DragAwareMouseListener {
|
|
|
83
109
|
}
|
|
84
110
|
|
|
85
111
|
mouseMove(target: SModelElement, event: MouseEvent): Action[] {
|
|
86
|
-
this.
|
|
112
|
+
this.marqueeUtil.updateCurrentPoint(getAbsolutePosition(target, event));
|
|
87
113
|
if (this.isActive) {
|
|
88
|
-
const nodeIdsSelected =
|
|
89
|
-
|
|
90
|
-
.all()
|
|
91
|
-
.map(e => e as SModelElement & BoundsAware)
|
|
92
|
-
.filter(e => isSelectable(e))
|
|
93
|
-
.filter(e => e instanceof SNode)
|
|
94
|
-
.filter(e => this.isNodeMarked(e))
|
|
95
|
-
.map(e => e.id)
|
|
96
|
-
);
|
|
97
|
-
const edgeIdsSelected = this.getMarkedEdges(target.root);
|
|
114
|
+
const nodeIdsSelected = this.nodes.filter(e => this.marqueeUtil.isNodeMarked(toAbsoluteBounds(e))).map(e => e.id);
|
|
115
|
+
const edgeIdsSelected = this.edges.filter(e => this.isEdgeMarked(e)).map(e => this.domHelper.findSModelIdByDOMElement(e));
|
|
98
116
|
const selected = nodeIdsSelected.concat(edgeIdsSelected);
|
|
99
117
|
return [
|
|
100
118
|
new SelectAction([], Array.from(target.root.index.all().map(e => e.id))),
|
|
101
119
|
new SelectAction(selected.concat(this.previouslySelected), []),
|
|
102
|
-
|
|
120
|
+
this.marqueeUtil.drawMarqueeAction()
|
|
103
121
|
];
|
|
104
122
|
}
|
|
105
123
|
return [];
|
|
@@ -113,131 +131,15 @@ export class MarqueeMouseListener extends DragAwareMouseListener {
|
|
|
113
131
|
return [new RemoveMarqueeAction(), new EnableDefaultToolsAction()];
|
|
114
132
|
}
|
|
115
133
|
|
|
116
|
-
getMarkedEdges(root: SModelElement): string[] {
|
|
117
|
-
const elements = Array.from(document.querySelectorAll('g'));
|
|
118
|
-
const edges = Array.from(
|
|
119
|
-
root.index
|
|
120
|
-
.all()
|
|
121
|
-
.filter(e => e instanceof SEdge)
|
|
122
|
-
.filter(e => isSelectable(e))
|
|
123
|
-
.map(e => e.id)
|
|
124
|
-
);
|
|
125
|
-
return elements
|
|
126
|
-
.filter(e => edges.includes(this.domHelper.findSModelIdByDOMElement(e)))
|
|
127
|
-
.filter(e => this.isEdgeMarked(e))
|
|
128
|
-
.map(e => this.domHelper.findSModelIdByDOMElement(e));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
134
|
isEdgeMarked(element: SVGElement): boolean {
|
|
132
135
|
if (!element.getAttribute('transform')) {
|
|
133
136
|
if (element.children[0]) {
|
|
134
137
|
const path = element.children[0].getAttribute('d');
|
|
135
|
-
|
|
136
|
-
const points = path.split(/M|L/);
|
|
137
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
138
|
-
const coord1 = points[i].split(',');
|
|
139
|
-
const coord2 = points[i + 1].split(',');
|
|
140
|
-
const point1 = { x: parseInt(coord1[0], 10), y: parseInt(coord1[1], 10) };
|
|
141
|
-
const point2 = { x: parseInt(coord2[0], 10), y: parseInt(coord2[1], 10) };
|
|
142
|
-
if (this.isLineMarked(point1, point2)) {
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
138
|
+
return this.marqueeUtil.isEdgePathMarked(path);
|
|
147
139
|
}
|
|
148
140
|
}
|
|
149
141
|
return false;
|
|
150
142
|
}
|
|
151
|
-
|
|
152
|
-
isLineMarked(point1: Point, point2: Point): boolean {
|
|
153
|
-
if (this.pointInRect(point1) || this.pointInRect(point2)) {
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
if (this.linesIntersect(point1, point2, this.startPoint, { x: this.startPoint.x, y: this.currentPoint.y })) {
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
if (this.linesIntersect(point1, point2, this.startPoint, { x: this.currentPoint.x, y: this.startPoint.y })) {
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
if (this.linesIntersect(point1, point2, { x: this.currentPoint.x, y: this.startPoint.y }, this.currentPoint)) {
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
if (this.linesIntersect(point1, point2, { x: this.startPoint.x, y: this.currentPoint.y }, this.currentPoint)) {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
linesIntersect(p1: Point, p2: Point, p3: Point, p4: Point): boolean {
|
|
172
|
-
const tCount = (p1.x - p3.x) * (p3.y - p4.y) - (p1.y - p3.y) * (p3.x - p4.x);
|
|
173
|
-
const tDenom = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);
|
|
174
|
-
const t = tCount / tDenom;
|
|
175
|
-
const uCount = (p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);
|
|
176
|
-
const uDenom = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);
|
|
177
|
-
const u = uCount / uDenom;
|
|
178
|
-
if (t >= 0.0 && t <= 1.0 && u >= 0.0 && u <= 1.0) {
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
pointInRect(point: Point): boolean {
|
|
185
|
-
const boolX =
|
|
186
|
-
this.startPoint.x <= this.currentPoint.x
|
|
187
|
-
? this.isBetween(point.x, this.startPoint.x, this.currentPoint.x)
|
|
188
|
-
: this.isBetween(point.x, this.currentPoint.x, this.startPoint.x);
|
|
189
|
-
const boolY =
|
|
190
|
-
this.startPoint.y <= this.currentPoint.y
|
|
191
|
-
? this.isBetween(point.y, this.startPoint.y, this.currentPoint.y)
|
|
192
|
-
: this.isBetween(point.y, this.currentPoint.y, this.startPoint.y);
|
|
193
|
-
return boolX && boolY;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
isNodeMarked(element: SModelElement & BoundsAware): boolean {
|
|
197
|
-
const horizontallyIn =
|
|
198
|
-
this.startPoint.x < this.currentPoint.x
|
|
199
|
-
? this.isElementBetweenXAxis(element, this.startPoint.x, this.currentPoint.x)
|
|
200
|
-
: this.isElementBetweenXAxis(element, this.currentPoint.x, this.startPoint.x);
|
|
201
|
-
const verticallyIn =
|
|
202
|
-
this.startPoint.y < this.currentPoint.y
|
|
203
|
-
? this.isElementBetweenYAxis(element, this.startPoint.y, this.currentPoint.y)
|
|
204
|
-
: this.isElementBetweenYAxis(element, this.currentPoint.y, this.startPoint.y);
|
|
205
|
-
if (horizontallyIn && verticallyIn) {
|
|
206
|
-
return true;
|
|
207
|
-
}
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
isElementBetweenXAxis(element: SModelElement & BoundsAware, marqueeLeft: number, marqueeRight: number): boolean {
|
|
212
|
-
if (
|
|
213
|
-
this.isBetween(marqueeLeft, toAbsoluteBounds(element).x, toAbsoluteBounds(element).x + toAbsoluteBounds(element).width) ||
|
|
214
|
-
this.isBetween(marqueeRight, toAbsoluteBounds(element).x, toAbsoluteBounds(element).x + toAbsoluteBounds(element).width)
|
|
215
|
-
) {
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
const leftEdge = this.isBetween(toAbsoluteBounds(element).x, marqueeLeft, marqueeRight);
|
|
219
|
-
const rightEdge = this.isBetween(toAbsoluteBounds(element).x + toAbsoluteBounds(element).width, marqueeLeft, marqueeRight);
|
|
220
|
-
return leftEdge || rightEdge;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
isElementBetweenYAxis(element: SModelElement & BoundsAware, marqueeTop: number, marqueeBottom: number): boolean {
|
|
224
|
-
if (
|
|
225
|
-
this.isBetween(marqueeTop, toAbsoluteBounds(element).y, toAbsoluteBounds(element).y + toAbsoluteBounds(element).height) ||
|
|
226
|
-
this.isBetween(marqueeBottom, toAbsoluteBounds(element).y, toAbsoluteBounds(element).y + toAbsoluteBounds(element).height)
|
|
227
|
-
) {
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
const topEdge = this.isBetween(toAbsoluteBounds(element).y, marqueeTop, marqueeBottom);
|
|
231
|
-
const bottomEdge = this.isBetween(toAbsoluteBounds(element).y + toAbsoluteBounds(element).height, marqueeTop, marqueeBottom);
|
|
232
|
-
return topEdge || bottomEdge;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
isBetween(x: number, lower: number, upper: number): boolean {
|
|
236
|
-
if (lower <= x && x <= upper) {
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
143
|
}
|
|
242
144
|
|
|
243
145
|
@injectable()
|
package/src/index.ts
CHANGED
|
@@ -88,6 +88,7 @@ export * from './features/tools/delete-tool';
|
|
|
88
88
|
export * from './features/tools/edge-creation-tool';
|
|
89
89
|
export * from './features/tools/edge-edit-tool';
|
|
90
90
|
export * from './features/tools/node-creation-tool';
|
|
91
|
+
export * from './features/tools/marquee-behavior';
|
|
91
92
|
export * from './features/validation/issue-marker';
|
|
92
93
|
export * from './features/validation/marker-navigator';
|
|
93
94
|
export * from './features/validation/validate';
|