@eclipse-glsp/client 2.1.0-next.293 → 2.1.0-next.295
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/lib/features/accessibility/move-zoom/move-handler.d.ts +23 -8
- package/lib/features/accessibility/move-zoom/move-handler.d.ts.map +1 -1
- package/lib/features/accessibility/move-zoom/move-handler.js +88 -53
- package/lib/features/accessibility/move-zoom/move-handler.js.map +1 -1
- package/lib/features/accessibility/resize-key-tool/resize-key-handler.d.ts +7 -2
- package/lib/features/accessibility/resize-key-tool/resize-key-handler.d.ts.map +1 -1
- package/lib/features/accessibility/resize-key-tool/resize-key-handler.js +22 -7
- package/lib/features/accessibility/resize-key-tool/resize-key-handler.js.map +1 -1
- package/lib/features/accessibility/search/search-palette.d.ts +1 -1
- package/lib/features/accessibility/search/search-palette.d.ts.map +1 -1
- package/lib/features/accessibility/search/search-palette.js +1 -1
- package/lib/features/accessibility/search/search-palette.js.map +1 -1
- package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts +2 -5
- 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 +21 -13
- package/lib/features/accessibility/view-key-tools/movement-key-tool.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts +16 -1
- 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 +2 -2
- package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/viewpoint-util.d.ts +8 -1
- package/lib/utils/viewpoint-util.d.ts.map +1 -1
- package/lib/utils/viewpoint-util.js +14 -1
- package/lib/utils/viewpoint-util.js.map +1 -1
- package/package.json +3 -3
- package/src/features/accessibility/move-zoom/move-handler.ts +105 -65
- package/src/features/accessibility/resize-key-tool/resize-key-handler.ts +32 -10
- package/src/features/accessibility/search/search-palette.ts +5 -5
- package/src/features/accessibility/view-key-tools/movement-key-tool.ts +21 -14
- package/src/features/tools/change-bounds/change-bounds-tool-feedback.ts +5 -5
- package/src/utils/viewpoint-util.ts +17 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { Bounds, BoundsAware, Dimension, GChildElement, Point,
|
|
16
|
+
import { Bounds, BoundsAware, Dimension, GChildElement, GModelElement, GModelRoot, Point, Viewport } from '@eclipse-glsp/sprotty';
|
|
17
17
|
import { BoundsAwareModelElement } from './gmodel-util';
|
|
18
18
|
/**
|
|
19
19
|
* Return the position corresponding to this mouse event (Browser coordinates)
|
|
@@ -69,4 +69,11 @@ export declare function absoluteToParent(element: BoundsAwareModelElement & GChi
|
|
|
69
69
|
* @returns the equivalent point, relative to the element's coordinates
|
|
70
70
|
*/
|
|
71
71
|
export declare function absoluteToLocal(element: BoundsAwareModelElement, absolutePoint: Point): Point;
|
|
72
|
+
/**
|
|
73
|
+
* Returns `true` if `point` is outside of the `viewport`.
|
|
74
|
+
* @param point The point to check.
|
|
75
|
+
* @param viewport The viewport.
|
|
76
|
+
* @returns `true` if `point` is outside, `false` otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export declare function outsideOfViewport(point: Point, viewport: GModelRoot & Viewport): boolean;
|
|
72
79
|
//# sourceMappingURL=viewpoint-util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewpoint-util.d.ts","sourceRoot":"","sources":["../../src/utils/viewpoint-util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAElF,OAAO,EACH,MAAM,EACN,WAAW,EACX,SAAS,EACT,aAAa,EACb,KAAK,EACL,
|
|
1
|
+
{"version":3,"file":"viewpoint-util.d.ts","sourceRoot":"","sources":["../../src/utils/viewpoint-util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAElF,OAAO,EACH,MAAM,EACN,WAAW,EACX,SAAS,EACT,aAAa,EACb,aAAa,EACb,UAAU,EACV,KAAK,EACL,QAAQ,EAMX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,GAAG,KAAK,CAExF;AACD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAsBrF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,WAAW,GAAG,MAAM,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,GAAG,KAAK,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,GAAG,SAAS,CAE7E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,EAAE,aAAa,EAAE,KAAK,GAAG,KAAK,CAM9G;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,KAAK,GAAG,KAAK,CAG7F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAOxF"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
16
16
|
********************************************************************************/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.absoluteToLocal = exports.absoluteToParent = exports.toAbsoluteSize = exports.toAbsolutePosition = exports.toAbsoluteBounds = exports.getAbsolutePositionByPoint = exports.getAbsolutePosition = void 0;
|
|
18
|
+
exports.outsideOfViewport = exports.absoluteToLocal = exports.absoluteToParent = exports.toAbsoluteSize = exports.toAbsolutePosition = exports.toAbsoluteBounds = exports.getAbsolutePositionByPoint = exports.getAbsolutePosition = void 0;
|
|
19
19
|
const sprotty_1 = require("@eclipse-glsp/sprotty");
|
|
20
20
|
/**
|
|
21
21
|
* Return the position corresponding to this mouse event (Browser coordinates)
|
|
@@ -119,4 +119,17 @@ function absoluteToLocal(element, absolutePoint) {
|
|
|
119
119
|
return { x: absolutePoint.x - absoluteElementBounds.x, y: absolutePoint.y - absoluteElementBounds.y };
|
|
120
120
|
}
|
|
121
121
|
exports.absoluteToLocal = absoluteToLocal;
|
|
122
|
+
/**
|
|
123
|
+
* Returns `true` if `point` is outside of the `viewport`.
|
|
124
|
+
* @param point The point to check.
|
|
125
|
+
* @param viewport The viewport.
|
|
126
|
+
* @returns `true` if `point` is outside, `false` otherwise.
|
|
127
|
+
*/
|
|
128
|
+
function outsideOfViewport(point, viewport) {
|
|
129
|
+
return (point.x < viewport.scroll.x ||
|
|
130
|
+
point.x > viewport.scroll.x + viewport.canvasBounds.width ||
|
|
131
|
+
point.y < viewport.scroll.y ||
|
|
132
|
+
point.y > viewport.scroll.y + viewport.canvasBounds.height);
|
|
133
|
+
}
|
|
134
|
+
exports.outsideOfViewport = outsideOfViewport;
|
|
122
135
|
//# sourceMappingURL=viewpoint-util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewpoint-util.js","sourceRoot":"","sources":["../../src/utils/viewpoint-util.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;kFAckF;;;AAElF,
|
|
1
|
+
{"version":3,"file":"viewpoint-util.js","sourceRoot":"","sources":["../../src/utils/viewpoint-util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eclipse-glsp/client",
|
|
3
|
-
"version": "2.1.0-next.
|
|
3
|
+
"version": "2.1.0-next.295+0c22eb6",
|
|
4
4
|
"description": "A sprotty-based client for GLSP",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eclipse",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"watch": "tsc -w"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@eclipse-glsp/sprotty": "2.1.0-next.
|
|
50
|
+
"@eclipse-glsp/sprotty": "2.1.0-next.295+0c22eb6",
|
|
51
51
|
"autocompleter": "^9.1.0",
|
|
52
52
|
"file-saver": "^2.0.5",
|
|
53
53
|
"lodash": "4.17.21"
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"publishConfig": {
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "0c22eb65d1e79fca017703f1238ef39bc33c06b9"
|
|
63
63
|
}
|
|
@@ -14,24 +14,34 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import { inject, injectable } from 'inversify';
|
|
18
|
-
import { throttle } from 'lodash';
|
|
19
17
|
import {
|
|
20
18
|
Action,
|
|
21
19
|
ChangeBoundsOperation,
|
|
20
|
+
DisposableCollection,
|
|
21
|
+
ElementAndBounds,
|
|
22
|
+
ElementMove,
|
|
23
|
+
GModelRoot,
|
|
22
24
|
IActionDispatcher,
|
|
23
25
|
IActionHandler,
|
|
24
26
|
ICommand,
|
|
27
|
+
ISnapper,
|
|
28
|
+
MoveAction,
|
|
25
29
|
Point,
|
|
26
|
-
GModelRoot,
|
|
27
30
|
SetViewportAction,
|
|
28
31
|
TYPES,
|
|
29
32
|
Viewport,
|
|
30
33
|
findParentByFeature,
|
|
34
|
+
isBoundsAware,
|
|
31
35
|
isViewport
|
|
32
36
|
} from '@eclipse-glsp/sprotty';
|
|
37
|
+
import { inject, injectable, optional } from 'inversify';
|
|
38
|
+
import { DebouncedFunc, debounce } from 'lodash';
|
|
33
39
|
import { EditorContextService } from '../../../base/editor-context-service';
|
|
40
|
+
import { IFeedbackActionDispatcher } from '../../../base/feedback/feedback-action-dispatcher';
|
|
34
41
|
import { SelectableBoundsAware, getElements, isSelectableAndBoundsAware } from '../../../utils/gmodel-util';
|
|
42
|
+
import { isValidMove } from '../../../utils/layout-utils';
|
|
43
|
+
import { outsideOfViewport } from '../../../utils/viewpoint-util';
|
|
44
|
+
import { IMovementRestrictor } from '../../change-bounds/movement-restrictor';
|
|
35
45
|
|
|
36
46
|
/**
|
|
37
47
|
* Action for triggering moving of the viewport.
|
|
@@ -77,6 +87,10 @@ export interface MoveElementAction extends Action {
|
|
|
77
87
|
* used to specify the amount to be moved in the y-axis
|
|
78
88
|
*/
|
|
79
89
|
moveY: number;
|
|
90
|
+
/**
|
|
91
|
+
* used to specify whether we should snap to the grid
|
|
92
|
+
*/
|
|
93
|
+
snap: boolean;
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
export namespace MoveElementAction {
|
|
@@ -86,24 +100,24 @@ export namespace MoveElementAction {
|
|
|
86
100
|
return Action.hasKind(object, KIND);
|
|
87
101
|
}
|
|
88
102
|
|
|
89
|
-
export function create(elementIds: string[], moveX: number, moveY: number): MoveElementAction {
|
|
90
|
-
return { kind: KIND, elementIds, moveX, moveY };
|
|
103
|
+
export function create(elementIds: string[], moveX: number, moveY: number, snap: boolean = true): MoveElementAction {
|
|
104
|
+
return { kind: KIND, elementIds, moveX, moveY, snap };
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
moving of the viewport.
|
|
108
|
+
/**
|
|
109
|
+
* Action handler for moving of the viewport.
|
|
110
|
+
*/
|
|
96
111
|
@injectable()
|
|
97
112
|
export class MoveViewportHandler implements IActionHandler {
|
|
98
113
|
@inject(EditorContextService)
|
|
99
114
|
protected editorContextService: EditorContextService;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
protected readonly throttledHandleViewportMove = throttle((action: MoveViewportAction) => this.handleMoveViewport(action), 150);
|
|
115
|
+
@inject(TYPES.IActionDispatcher)
|
|
116
|
+
protected dispatcher: IActionDispatcher;
|
|
103
117
|
|
|
104
118
|
handle(action: Action): void | Action | ICommand {
|
|
105
119
|
if (MoveViewportAction.is(action)) {
|
|
106
|
-
this.
|
|
120
|
+
this.handleMoveViewport(action);
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
|
|
@@ -123,87 +137,113 @@ export class MoveViewportHandler implements IActionHandler {
|
|
|
123
137
|
},
|
|
124
138
|
zoom: viewport.zoom
|
|
125
139
|
};
|
|
126
|
-
|
|
127
|
-
return SetViewportAction.create(viewport.id, newViewport, { animate: true });
|
|
140
|
+
return SetViewportAction.create(viewport.id, newViewport, { animate: false });
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
moving elements.
|
|
144
|
+
/**
|
|
145
|
+
* Action handler for moving elements.
|
|
146
|
+
*/
|
|
133
147
|
@injectable()
|
|
134
148
|
export class MoveElementHandler implements IActionHandler {
|
|
135
149
|
@inject(EditorContextService)
|
|
136
150
|
protected editorContextService: EditorContextService;
|
|
137
|
-
|
|
138
|
-
|
|
151
|
+
|
|
152
|
+
@inject(TYPES.IActionDispatcher)
|
|
153
|
+
protected dispatcher: IActionDispatcher;
|
|
154
|
+
|
|
155
|
+
@inject(TYPES.IFeedbackActionDispatcher)
|
|
156
|
+
protected feedbackDispatcher: IFeedbackActionDispatcher;
|
|
157
|
+
|
|
158
|
+
@inject(TYPES.ISnapper)
|
|
159
|
+
@optional()
|
|
160
|
+
readonly snapper?: ISnapper;
|
|
161
|
+
|
|
162
|
+
@inject(TYPES.IMovementRestrictor)
|
|
163
|
+
@optional()
|
|
164
|
+
readonly movementRestrictor?: IMovementRestrictor;
|
|
165
|
+
|
|
166
|
+
protected debouncedChangeBounds?: DebouncedFunc<() => void>;
|
|
167
|
+
protected disposableFeedback = new DisposableCollection();
|
|
139
168
|
|
|
140
169
|
handle(action: Action): void | Action | ICommand {
|
|
141
170
|
if (MoveElementAction.is(action)) {
|
|
142
|
-
this.
|
|
171
|
+
this.handleMoveElement(action);
|
|
143
172
|
}
|
|
144
173
|
}
|
|
145
174
|
|
|
146
175
|
handleMoveElement(action: MoveElementAction): void {
|
|
147
|
-
const
|
|
176
|
+
const modelRoot = this.editorContextService.modelRoot;
|
|
177
|
+
const viewport = findParentByFeature(modelRoot, isViewport);
|
|
148
178
|
if (!viewport) {
|
|
149
179
|
return;
|
|
150
180
|
}
|
|
151
181
|
|
|
152
|
-
const
|
|
182
|
+
const viewportActions: Action[] = [];
|
|
183
|
+
const elementMoves: ElementMove[] = [];
|
|
184
|
+
const elements = getElements(modelRoot.index, action.elementIds, isSelectableAndBoundsAware);
|
|
185
|
+
for (const element of elements) {
|
|
186
|
+
const newPosition = this.getTargetBounds(element, action);
|
|
187
|
+
elementMoves.push({
|
|
188
|
+
elementId: element.id,
|
|
189
|
+
fromPosition: {
|
|
190
|
+
x: element.bounds.x,
|
|
191
|
+
y: element.bounds.y
|
|
192
|
+
},
|
|
193
|
+
toPosition: newPosition
|
|
194
|
+
});
|
|
195
|
+
if (outsideOfViewport(newPosition, viewport)) {
|
|
196
|
+
viewportActions.push(MoveViewportAction.create(action.moveX, action.moveY));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
153
199
|
|
|
154
|
-
this.dispatcher.dispatchAll(
|
|
155
|
-
|
|
200
|
+
this.dispatcher.dispatchAll(viewportActions);
|
|
201
|
+
const moveAction = MoveAction.create(elementMoves, { animate: false });
|
|
202
|
+
this.disposableFeedback.push(this.feedbackDispatcher.registerFeedback(this, [moveAction]));
|
|
156
203
|
|
|
157
|
-
|
|
158
|
-
return { x: element.bounds.x + offSetX, y: element.bounds.y + offSetY };
|
|
204
|
+
this.scheduleChangeBounds(this.toElementAndBounds(elementMoves));
|
|
159
205
|
}
|
|
160
206
|
|
|
161
|
-
protected
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
newPoint.x > viewport.scroll.x + viewport.canvasBounds.width ||
|
|
170
|
-
newPoint.y < viewport.scroll.y ||
|
|
171
|
-
newPoint.y > viewport.scroll.y + viewport.canvasBounds.height
|
|
172
|
-
) {
|
|
173
|
-
return MoveViewportAction.create(moveX, moveY);
|
|
207
|
+
protected getTargetBounds(element: SelectableBoundsAware, action: MoveElementAction): Point {
|
|
208
|
+
let position = { x: element.bounds.x + action.moveX, y: element.bounds.y + action.moveY };
|
|
209
|
+
if (this.snapper && action.snap) {
|
|
210
|
+
position = this.snapper.snap(position, element);
|
|
211
|
+
}
|
|
212
|
+
if (!isValidMove(element, position, this.movementRestrictor)) {
|
|
213
|
+
// reset to position before the move, if not valid
|
|
214
|
+
position = { x: element.bounds.x, y: element.bounds.y };
|
|
174
215
|
}
|
|
175
|
-
return;
|
|
216
|
+
return position;
|
|
176
217
|
}
|
|
177
218
|
|
|
178
|
-
protected
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
newPosition: {
|
|
187
|
-
x: element.bounds.x + offSetX,
|
|
188
|
-
y: element.bounds.y + offSetY
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
]);
|
|
219
|
+
protected scheduleChangeBounds(elementAndBounds: ElementAndBounds[]): void {
|
|
220
|
+
this.debouncedChangeBounds?.cancel();
|
|
221
|
+
this.debouncedChangeBounds = debounce(() => {
|
|
222
|
+
this.disposableFeedback.dispose();
|
|
223
|
+
this.dispatcher.dispatchAll([ChangeBoundsOperation.create(elementAndBounds)]);
|
|
224
|
+
this.debouncedChangeBounds = undefined;
|
|
225
|
+
}, 300);
|
|
226
|
+
this.debouncedChangeBounds();
|
|
192
227
|
}
|
|
193
228
|
|
|
194
|
-
protected
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
229
|
+
protected toElementAndBounds(elementMoves: ElementMove[]): ElementAndBounds[] {
|
|
230
|
+
const elementBounds: ElementAndBounds[] = [];
|
|
231
|
+
for (const elementMove of elementMoves) {
|
|
232
|
+
const element = this.editorContextService.modelRoot.index.getById(elementMove.elementId);
|
|
233
|
+
if (element && isBoundsAware(element)) {
|
|
234
|
+
elementBounds.push({
|
|
235
|
+
elementId: elementMove.elementId,
|
|
236
|
+
newSize: {
|
|
237
|
+
height: element.bounds.height,
|
|
238
|
+
width: element.bounds.width
|
|
239
|
+
},
|
|
240
|
+
newPosition: {
|
|
241
|
+
x: elementMove.toPosition.x,
|
|
242
|
+
y: elementMove.toPosition.y
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
206
246
|
}
|
|
207
|
-
return
|
|
247
|
+
return elementBounds;
|
|
208
248
|
}
|
|
209
249
|
}
|
|
@@ -14,23 +14,28 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import { inject, injectable, optional } from 'inversify';
|
|
18
17
|
import {
|
|
19
18
|
Action,
|
|
20
19
|
ChangeBoundsOperation,
|
|
21
20
|
Dimension,
|
|
21
|
+
DisposableCollection,
|
|
22
|
+
ElementAndBounds,
|
|
23
|
+
GModelElement,
|
|
24
|
+
GParentElement,
|
|
22
25
|
IActionDispatcher,
|
|
23
26
|
IActionHandler,
|
|
24
27
|
ICommand,
|
|
25
28
|
ISnapper,
|
|
26
29
|
Point,
|
|
27
|
-
|
|
28
|
-
GParentElement,
|
|
30
|
+
SetBoundsAction,
|
|
29
31
|
TYPES
|
|
30
32
|
} from '@eclipse-glsp/sprotty';
|
|
33
|
+
import { inject, injectable, optional } from 'inversify';
|
|
34
|
+
import { DebouncedFunc, debounce } from 'lodash';
|
|
31
35
|
import { EditorContextService } from '../../../base/editor-context-service';
|
|
32
|
-
import {
|
|
36
|
+
import { IFeedbackActionDispatcher } from '../../../base/feedback/feedback-action-dispatcher';
|
|
33
37
|
import { SelectableBoundsAware, getElements, isSelectableAndBoundsAware, toElementAndBounds } from '../../../utils/gmodel-util';
|
|
38
|
+
import { isValidMove, isValidSize, minHeight, minWidth } from '../../../utils/layout-utils';
|
|
34
39
|
import { Resizable } from '../../change-bounds/model';
|
|
35
40
|
import { GridSnapper } from '../../change-bounds/snap';
|
|
36
41
|
|
|
@@ -67,7 +72,14 @@ export class ResizeElementHandler implements IActionHandler {
|
|
|
67
72
|
@inject(EditorContextService)
|
|
68
73
|
protected editorContextService: EditorContextService;
|
|
69
74
|
|
|
70
|
-
@inject(TYPES.IActionDispatcher)
|
|
75
|
+
@inject(TYPES.IActionDispatcher)
|
|
76
|
+
protected dispatcher: IActionDispatcher;
|
|
77
|
+
|
|
78
|
+
@inject(TYPES.IFeedbackActionDispatcher)
|
|
79
|
+
protected feedbackDispatcher: IFeedbackActionDispatcher;
|
|
80
|
+
|
|
81
|
+
protected debouncedChangeBounds?: DebouncedFunc<() => void>;
|
|
82
|
+
protected disposableFeedback = new DisposableCollection();
|
|
71
83
|
|
|
72
84
|
// Default x resize used if GridSnapper is not provided
|
|
73
85
|
static readonly defaultResizeX = 20;
|
|
@@ -92,11 +104,21 @@ export class ResizeElementHandler implements IActionHandler {
|
|
|
92
104
|
|
|
93
105
|
handleResizeElement(action: ResizeElementAction): void {
|
|
94
106
|
const elements = getElements(this.editorContextService.modelRoot.index, action.elementIds, isSelectableAndBoundsAware);
|
|
95
|
-
this.
|
|
107
|
+
const elementAndBounds = this.computeElementAndBounds(elements, action);
|
|
108
|
+
|
|
109
|
+
this.disposableFeedback.push(this.feedbackDispatcher.registerFeedback(this, [SetBoundsAction.create(elementAndBounds)]));
|
|
110
|
+
|
|
111
|
+
this.debouncedChangeBounds?.cancel();
|
|
112
|
+
this.debouncedChangeBounds = debounce(() => {
|
|
113
|
+
this.disposableFeedback.dispose();
|
|
114
|
+
this.dispatcher.dispatchAll([ChangeBoundsOperation.create(elementAndBounds)]);
|
|
115
|
+
this.debouncedChangeBounds = undefined;
|
|
116
|
+
}, 300);
|
|
117
|
+
this.debouncedChangeBounds();
|
|
96
118
|
}
|
|
97
119
|
|
|
98
|
-
protected
|
|
99
|
-
const
|
|
120
|
+
protected computeElementAndBounds(elements: SelectableBoundsAware[], action: ResizeElementAction): ElementAndBounds[] {
|
|
121
|
+
const elementAndBounds: ElementAndBounds[] = [];
|
|
100
122
|
|
|
101
123
|
elements.forEach(element => {
|
|
102
124
|
const { x, y, width: oldWidth, height: oldHeight } = element.bounds;
|
|
@@ -116,11 +138,11 @@ export class ResizeElementHandler implements IActionHandler {
|
|
|
116
138
|
|
|
117
139
|
if (this.isValidBoundChange(element, { x, y }, { width, height })) {
|
|
118
140
|
const resizeElement = { id: element.id, bounds: { x, y, width, height } } as GModelElement & GParentElement & Resizable;
|
|
119
|
-
|
|
141
|
+
elementAndBounds.push(toElementAndBounds(resizeElement));
|
|
120
142
|
}
|
|
121
143
|
});
|
|
122
144
|
|
|
123
|
-
return
|
|
145
|
+
return elementAndBounds;
|
|
124
146
|
}
|
|
125
147
|
|
|
126
148
|
protected isValidBoundChange(element: SelectableBoundsAware, newPosition: Point, newSize: Dimension): boolean {
|
|
@@ -14,27 +14,27 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import { injectable } from 'inversify';
|
|
18
|
-
import { isEqual } from 'lodash';
|
|
19
|
-
import { toArray } from 'sprotty/lib/utils/iterable';
|
|
20
17
|
import {
|
|
21
18
|
Action,
|
|
22
19
|
CenterAction,
|
|
23
|
-
LabeledAction,
|
|
24
20
|
GModelElement,
|
|
25
21
|
GModelRoot,
|
|
26
22
|
GNode,
|
|
23
|
+
LabeledAction,
|
|
27
24
|
SelectAction,
|
|
28
25
|
SelectAllAction,
|
|
29
26
|
codiconCSSString,
|
|
30
27
|
isNameable,
|
|
31
28
|
name
|
|
32
29
|
} from '@eclipse-glsp/sprotty';
|
|
30
|
+
import { injectable } from 'inversify';
|
|
31
|
+
import { isEqual } from 'lodash';
|
|
32
|
+
import { toArray } from 'sprotty/lib/utils/iterable';
|
|
33
33
|
import { BaseAutocompletePalette } from '../../../base/auto-complete/base-autocomplete-palette';
|
|
34
34
|
|
|
35
|
+
import { AutocompleteSuggestion, IAutocompleteSuggestionProvider } from '../../../base/auto-complete/autocomplete-suggestion-providers';
|
|
35
36
|
import { applyCssClasses, deleteCssClasses } from '../../../base/feedback/css-feedback';
|
|
36
37
|
import { RepositionAction } from '../../../features/viewport/reposition';
|
|
37
|
-
import { AutocompleteSuggestion, IAutocompleteSuggestionProvider } from '../../../base/auto-complete/autocomplete-suggestion-providers';
|
|
38
38
|
import { GEdge } from '../../../model';
|
|
39
39
|
|
|
40
40
|
const CSS_SEARCH_HIDDEN = 'search-hidden';
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
+
import { Action, GModelElement, ISnapper, KeyListener, KeyTool, Point, TYPES } from '@eclipse-glsp/sprotty';
|
|
17
18
|
import { inject, injectable, optional } from 'inversify';
|
|
18
19
|
import { matchesKeystroke } from 'sprotty/lib/utils/keyboard';
|
|
19
|
-
import { Action, ISnapper, KeyListener, KeyTool, GModelElement, TYPES } from '@eclipse-glsp/sprotty';
|
|
20
20
|
import { GLSPActionDispatcher } from '../../../base/action-dispatcher';
|
|
21
21
|
import { SelectionService } from '../../../base/selection-service';
|
|
22
22
|
import { Tool } from '../../../base/tool-manager/tool';
|
|
@@ -63,14 +63,18 @@ export class MoveKeyListener extends KeyListener implements AccessibleKeyShortcu
|
|
|
63
63
|
|
|
64
64
|
protected readonly token = MoveKeyListener.name;
|
|
65
65
|
|
|
66
|
-
protected grid = { x: MoveKeyListener.defaultMoveX, y: MoveKeyListener.defaultMoveY };
|
|
67
|
-
|
|
68
66
|
constructor(protected readonly tool: MovementKeyTool) {
|
|
69
67
|
super();
|
|
68
|
+
}
|
|
70
69
|
|
|
70
|
+
protected get grid(): Point {
|
|
71
71
|
if (this.tool.snapper instanceof GridSnapper) {
|
|
72
|
-
|
|
72
|
+
return this.tool.snapper.grid;
|
|
73
73
|
}
|
|
74
|
+
return {
|
|
75
|
+
x: MoveKeyListener.defaultMoveX,
|
|
76
|
+
y: MoveKeyListener.defaultMoveY
|
|
77
|
+
};
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
registerShortcutKey(): void {
|
|
@@ -84,22 +88,25 @@ export class MoveKeyListener extends KeyListener implements AccessibleKeyShortcu
|
|
|
84
88
|
|
|
85
89
|
override keyDown(element: GModelElement, event: KeyboardEvent): Action[] {
|
|
86
90
|
const selectedElementIds = this.tool.selectionService.getSelectedElementIDs();
|
|
91
|
+
const snap = !event.altKey;
|
|
92
|
+
const offsetX = snap ? this.grid.x : 1;
|
|
93
|
+
const offsetY = snap ? this.grid.y : 1;
|
|
87
94
|
|
|
88
95
|
if (selectedElementIds.length > 0) {
|
|
89
96
|
if (this.matchesMoveUpKeystroke(event)) {
|
|
90
|
-
return [MoveElementAction.create(selectedElementIds, 0, -
|
|
97
|
+
return [MoveElementAction.create(selectedElementIds, 0, -offsetY, snap)];
|
|
91
98
|
} else if (this.matchesMoveDownKeystroke(event)) {
|
|
92
|
-
return [MoveElementAction.create(selectedElementIds, 0,
|
|
99
|
+
return [MoveElementAction.create(selectedElementIds, 0, offsetY, snap)];
|
|
93
100
|
} else if (this.matchesMoveRightKeystroke(event)) {
|
|
94
|
-
return [MoveElementAction.create(selectedElementIds,
|
|
101
|
+
return [MoveElementAction.create(selectedElementIds, offsetX, 0, snap)];
|
|
95
102
|
} else if (this.matchesMoveLeftKeystroke(event)) {
|
|
96
|
-
return [MoveElementAction.create(selectedElementIds, -
|
|
103
|
+
return [MoveElementAction.create(selectedElementIds, -offsetX, 0, snap)];
|
|
97
104
|
}
|
|
98
105
|
} else {
|
|
99
106
|
if (this.matchesMoveUpKeystroke(event)) {
|
|
100
|
-
return [MoveViewportAction.create(0, -this.grid.
|
|
107
|
+
return [MoveViewportAction.create(0, -this.grid.y)];
|
|
101
108
|
} else if (this.matchesMoveDownKeystroke(event)) {
|
|
102
|
-
return [MoveViewportAction.create(0, this.grid.
|
|
109
|
+
return [MoveViewportAction.create(0, this.grid.y)];
|
|
103
110
|
} else if (this.matchesMoveRightKeystroke(event)) {
|
|
104
111
|
return [MoveViewportAction.create(this.grid.x, 0)];
|
|
105
112
|
} else if (this.matchesMoveLeftKeystroke(event)) {
|
|
@@ -110,18 +117,18 @@ export class MoveKeyListener extends KeyListener implements AccessibleKeyShortcu
|
|
|
110
117
|
}
|
|
111
118
|
|
|
112
119
|
protected matchesMoveUpKeystroke(event: KeyboardEvent): boolean {
|
|
113
|
-
return matchesKeystroke(event, 'ArrowUp');
|
|
120
|
+
return matchesKeystroke(event, 'ArrowUp') || matchesKeystroke(event, 'ArrowUp', 'alt');
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
protected matchesMoveDownKeystroke(event: KeyboardEvent): boolean {
|
|
117
|
-
return matchesKeystroke(event, 'ArrowDown');
|
|
124
|
+
return matchesKeystroke(event, 'ArrowDown') || matchesKeystroke(event, 'ArrowDown', 'alt');
|
|
118
125
|
}
|
|
119
126
|
|
|
120
127
|
protected matchesMoveRightKeystroke(event: KeyboardEvent): boolean {
|
|
121
|
-
return matchesKeystroke(event, 'ArrowRight');
|
|
128
|
+
return matchesKeystroke(event, 'ArrowRight') || matchesKeystroke(event, 'ArrowRight', 'alt');
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
protected matchesMoveLeftKeystroke(event: KeyboardEvent): boolean {
|
|
125
|
-
return matchesKeystroke(event, 'ArrowLeft');
|
|
132
|
+
return matchesKeystroke(event, 'ArrowLeft') || matchesKeystroke(event, 'ArrowLeft', 'alt');
|
|
126
133
|
}
|
|
127
134
|
}
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { inject, injectable } from 'inversify';
|
|
17
|
-
import { VNode } from 'snabbdom';
|
|
18
16
|
import {
|
|
19
17
|
Action,
|
|
20
18
|
CommandExecutionContext,
|
|
@@ -22,11 +20,11 @@ import {
|
|
|
22
20
|
Disposable,
|
|
23
21
|
ElementMove,
|
|
24
22
|
GChildElement,
|
|
23
|
+
GModelElement,
|
|
24
|
+
GModelRoot,
|
|
25
25
|
MouseListener,
|
|
26
26
|
MoveAction,
|
|
27
27
|
Point,
|
|
28
|
-
GModelElement,
|
|
29
|
-
GModelRoot,
|
|
30
28
|
TYPES,
|
|
31
29
|
findParentByFeature,
|
|
32
30
|
hasStringProp,
|
|
@@ -34,6 +32,8 @@ import {
|
|
|
34
32
|
isSelectable,
|
|
35
33
|
isViewport
|
|
36
34
|
} from '@eclipse-glsp/sprotty';
|
|
35
|
+
import { inject, injectable } from 'inversify';
|
|
36
|
+
import { VNode } from 'snabbdom';
|
|
37
37
|
|
|
38
38
|
import { CursorCSS, cursorFeedbackAction } from '../../../base/feedback/css-feedback';
|
|
39
39
|
import { FeedbackCommand } from '../../../base/feedback/feedback-command';
|
|
@@ -197,7 +197,7 @@ export class FeedbackMoveMouseListener extends MouseListener implements Disposab
|
|
|
197
197
|
y: (event.pageY - this.startDragPosition.y) / zoom
|
|
198
198
|
};
|
|
199
199
|
|
|
200
|
-
const elementMoves: ElementMove[] = this.getElementMovesForDelta(target, delta, !event.
|
|
200
|
+
const elementMoves: ElementMove[] = this.getElementMovesForDelta(target, delta, !event.altKey, finished);
|
|
201
201
|
if (elementMoves.length > 0) {
|
|
202
202
|
return MoveAction.create(elementMoves, { animate: false, finished });
|
|
203
203
|
} else {
|
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
BoundsAware,
|
|
20
20
|
Dimension,
|
|
21
21
|
GChildElement,
|
|
22
|
-
Point,
|
|
23
22
|
GModelElement,
|
|
23
|
+
GModelRoot,
|
|
24
|
+
Point,
|
|
24
25
|
Viewport,
|
|
25
26
|
findParentByFeature,
|
|
26
27
|
isAlignable,
|
|
@@ -133,3 +134,18 @@ export function absoluteToLocal(element: BoundsAwareModelElement, absolutePoint:
|
|
|
133
134
|
const absoluteElementBounds = toAbsoluteBounds(element);
|
|
134
135
|
return { x: absolutePoint.x - absoluteElementBounds.x, y: absolutePoint.y - absoluteElementBounds.y };
|
|
135
136
|
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns `true` if `point` is outside of the `viewport`.
|
|
140
|
+
* @param point The point to check.
|
|
141
|
+
* @param viewport The viewport.
|
|
142
|
+
* @returns `true` if `point` is outside, `false` otherwise.
|
|
143
|
+
*/
|
|
144
|
+
export function outsideOfViewport(point: Point, viewport: GModelRoot & Viewport): boolean {
|
|
145
|
+
return (
|
|
146
|
+
point.x < viewport.scroll.x ||
|
|
147
|
+
point.x > viewport.scroll.x + viewport.canvasBounds.width ||
|
|
148
|
+
point.y < viewport.scroll.y ||
|
|
149
|
+
point.y > viewport.scroll.y + viewport.canvasBounds.height
|
|
150
|
+
);
|
|
151
|
+
}
|