@eclipse-glsp/client 1.0.0 → 1.1.0-RC02
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/base/types.d.ts +2 -0
- package/lib/base/types.d.ts.map +1 -1
- package/lib/features/export/glsp-svg-exporter.d.ts +22 -0
- package/lib/features/export/glsp-svg-exporter.d.ts.map +1 -0
- package/lib/features/export/glsp-svg-exporter.js +45 -0
- package/lib/features/export/glsp-svg-exporter.js.map +1 -0
- package/lib/features/layout/di.config.d.ts.map +1 -1
- package/lib/features/layout/di.config.js +2 -0
- package/lib/features/layout/di.config.js.map +1 -1
- package/lib/features/layout/hbox-layout.d.ts +1 -1
- package/lib/features/layout/hbox-layout.d.ts.map +1 -1
- package/lib/features/layout/hbox-layout.js +19 -7
- package/lib/features/layout/hbox-layout.js.map +1 -1
- package/lib/features/layout/layouter.d.ts +37 -0
- package/lib/features/layout/layouter.d.ts.map +1 -0
- package/lib/features/layout/layouter.js +131 -0
- package/lib/features/layout/layouter.js.map +1 -0
- package/lib/features/layout/tests/freeform-layout.spec.d.ts +3 -0
- package/lib/features/layout/tests/freeform-layout.spec.d.ts.map +1 -0
- package/lib/features/layout/tests/freeform-layout.spec.js +201 -0
- package/lib/features/layout/tests/freeform-layout.spec.js.map +1 -0
- package/lib/features/layout/tests/hbox-layout.spec.d.ts +3 -0
- package/lib/features/layout/tests/hbox-layout.spec.d.ts.map +1 -0
- package/lib/features/layout/tests/hbox-layout.spec.js +161 -0
- package/lib/features/layout/tests/hbox-layout.spec.js.map +1 -0
- package/lib/features/layout/tests/layouter-test-util.d.ts +34 -0
- package/lib/features/layout/tests/layouter-test-util.d.ts.map +1 -0
- package/lib/features/layout/tests/layouter-test-util.js +96 -0
- package/lib/features/layout/tests/layouter-test-util.js.map +1 -0
- package/lib/features/layout/tests/vbox-layout.spec.d.ts +3 -0
- package/lib/features/layout/tests/vbox-layout.spec.d.ts.map +1 -0
- package/lib/features/layout/tests/vbox-layout.spec.js +161 -0
- package/lib/features/layout/tests/vbox-layout.spec.js.map +1 -0
- package/lib/features/layout/vbox-layout.d.ts +1 -1
- package/lib/features/layout/vbox-layout.d.ts.map +1 -1
- package/lib/features/layout/vbox-layout.js +17 -5
- package/lib/features/layout/vbox-layout.js.map +1 -1
- package/lib/features/tools/change-bounds-tool.d.ts.map +1 -1
- package/lib/features/tools/change-bounds-tool.js +13 -10
- package/lib/features/tools/change-bounds-tool.js.map +1 -1
- package/lib/features/tools/di.config.d.ts.map +1 -1
- package/lib/features/tools/di.config.js +4 -1
- package/lib/features/tools/di.config.js.map +1 -1
- package/lib/features/tools/edge-edit-tool.d.ts +2 -2
- package/lib/features/tools/edge-edit-tool.d.ts.map +1 -1
- package/lib/features/tools/edge-edit-tool.js +3 -2
- package/lib/features/tools/edge-edit-tool.js.map +1 -1
- package/lib/sprotty-reexport.d.ts +1 -1
- package/lib/sprotty-reexport.d.ts.map +1 -1
- package/lib/sprotty-reexport.js +6 -4
- package/lib/sprotty-reexport.js.map +1 -1
- package/lib/utils/smodel-util.d.ts +11 -2
- package/lib/utils/smodel-util.d.ts.map +1 -1
- package/lib/utils/smodel-util.js +17 -2
- package/lib/utils/smodel-util.js.map +1 -1
- package/lib/views/glsp-projection-view.d.ts.map +1 -1
- package/lib/views/glsp-projection-view.js +8 -2
- package/lib/views/glsp-projection-view.js.map +1 -1
- package/package.json +6 -5
- package/src/features/export/glsp-svg-exporter.ts +50 -0
- package/src/features/layout/di.config.ts +3 -1
- package/src/features/layout/hbox-layout.ts +24 -7
- package/src/features/layout/layouter.ts +137 -0
- package/src/features/layout/tests/freeform-layout.spec.ts +216 -0
- package/src/features/layout/tests/hbox-layout.spec.ts +171 -0
- package/src/features/layout/tests/layouter-test-util.ts +122 -0
- package/src/features/layout/tests/vbox-layout.spec.ts +171 -0
- package/src/features/layout/vbox-layout.ts +22 -5
- package/src/features/tools/change-bounds-tool.ts +16 -13
- package/src/features/tools/di.config.ts +5 -1
- package/src/features/tools/edge-edit-tool.ts +5 -6
- package/src/sprotty-reexport.ts +6 -1
- package/src/utils/smodel-util.ts +20 -1
- package/src/views/glsp-projection-view.tsx +10 -3
|
@@ -49,6 +49,9 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
49
49
|
|
|
50
50
|
const fixedSize = this.getFixedContainerBounds(container, options, layouter);
|
|
51
51
|
|
|
52
|
+
const currentWidth = (boundsData.bounds?.width || 0) - options.paddingLeft - options.paddingRight;
|
|
53
|
+
const currentHeight = (boundsData.bounds?.height || 0) - options.paddingTop - options.paddingBottom;
|
|
54
|
+
|
|
52
55
|
const maxWidth =
|
|
53
56
|
options.paddingFactor *
|
|
54
57
|
(options.resizeContainer
|
|
@@ -60,8 +63,11 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
60
63
|
? Math.max(fixedSize.height - options.paddingTop - options.paddingBottom, childrenSize.height)
|
|
61
64
|
: Math.max(0, fixedSize.height - options.paddingTop - options.paddingBottom));
|
|
62
65
|
|
|
66
|
+
const width = Math.max(currentWidth, maxWidth);
|
|
67
|
+
const height = Math.max(currentHeight, maxHeight);
|
|
68
|
+
|
|
63
69
|
// Remaining size that can be grabbed by children with the vGrab option
|
|
64
|
-
const grabHeight: number =
|
|
70
|
+
const grabHeight: number = height - childrenSize.height;
|
|
65
71
|
// Number of children that request vGrab
|
|
66
72
|
// FIXME: This approach works fine when only 1 child uses VGrab, but may cause rounding issues
|
|
67
73
|
// when the grabHeight can't be equally shared by all children.
|
|
@@ -70,7 +76,7 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
70
76
|
.filter(opt => opt.vGrab).length;
|
|
71
77
|
|
|
72
78
|
if (maxWidth > 0 && maxHeight > 0) {
|
|
73
|
-
const offset = this.layoutChildren(container, layouter, options,
|
|
79
|
+
const offset = this.layoutChildren(container, layouter, options, width, height, grabHeight, grabbingChildren);
|
|
74
80
|
boundsData.bounds = this.getFinalContainerBounds(container, offset, options, childrenSize.width, childrenSize.height);
|
|
75
81
|
boundsData.boundsChanged = true;
|
|
76
82
|
}
|
|
@@ -155,7 +161,14 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
155
161
|
grabHeight?: number,
|
|
156
162
|
grabbingChildren?: number
|
|
157
163
|
): Point {
|
|
164
|
+
const hAlign = childOptions.hGrab ? 'left' : childOptions.hAlign;
|
|
165
|
+
const dx = this.getDx(hAlign, bounds, maxWidth);
|
|
158
166
|
let offset = super.layoutChild(child, boundsData, bounds, childOptions, containerOptions, currentOffset, maxWidth, maxHeight);
|
|
167
|
+
boundsData.bounds = {
|
|
168
|
+
...boundsData.bounds!,
|
|
169
|
+
x: currentOffset.x + dx,
|
|
170
|
+
y: currentOffset.y
|
|
171
|
+
};
|
|
159
172
|
if (childOptions.hGrab) {
|
|
160
173
|
boundsData.bounds = {
|
|
161
174
|
x: boundsData.bounds!.x,
|
|
@@ -197,7 +210,7 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
197
210
|
}
|
|
198
211
|
|
|
199
212
|
protected override getChildLayoutOptions(child: SChildElement, containerOptions: VBoxLayoutOptionsExt): VBoxLayoutOptionsExt {
|
|
200
|
-
return super.getChildLayoutOptions(child, containerOptions) as VBoxLayoutOptionsExt;
|
|
213
|
+
return super.getChildLayoutOptions(child, this.filterContainerOptions(containerOptions)) as VBoxLayoutOptionsExt;
|
|
201
214
|
}
|
|
202
215
|
|
|
203
216
|
protected override getLayoutOptions(element: SModelElement): VBoxLayoutOptionsExt {
|
|
@@ -250,7 +263,11 @@ export class VBoxLayouterExt extends VBoxLayouter {
|
|
|
250
263
|
};
|
|
251
264
|
}
|
|
252
265
|
|
|
253
|
-
protected
|
|
254
|
-
|
|
266
|
+
protected filterContainerOptions(containerOptions: VBoxLayoutOptionsExt): VBoxLayoutOptionsExt {
|
|
267
|
+
// Reset object-specific layout options to default before merging,
|
|
268
|
+
// to make sure they won't be inherited (grab, prefSize)
|
|
269
|
+
// eslint-disable-next-line no-null/no-null
|
|
270
|
+
const localOptions = { vGrab: false, hGrab: false, prefHeight: null, prefWidth: null };
|
|
271
|
+
return { ...containerOptions, ...localOptions };
|
|
255
272
|
}
|
|
256
273
|
}
|
|
@@ -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 {
|
|
16
|
+
import {
|
|
17
17
|
Action,
|
|
18
18
|
Bounds,
|
|
19
19
|
ChangeBoundsOperation,
|
|
@@ -44,10 +44,10 @@ import { DragAwareMouseListener } from '../../base/drag-aware-mouse-listener';
|
|
|
44
44
|
import { TYPES } from '../../base/types';
|
|
45
45
|
import { isValidMove, isValidSize } from '../../utils/layout-utils';
|
|
46
46
|
import {
|
|
47
|
+
calcElementAndRoutingPoints,
|
|
47
48
|
forEachElement,
|
|
48
49
|
isNonRoutableSelectedMovableBoundsAware,
|
|
49
|
-
toElementAndBounds
|
|
50
|
-
toElementAndRoutingPoints
|
|
50
|
+
toElementAndBounds
|
|
51
51
|
} from '../../utils/smodel-util';
|
|
52
52
|
import { isBoundsAwareMoveable, isResizable, Resizable, ResizeHandleLocation, SResizeHandle } from '../change-bounds/model';
|
|
53
53
|
import {
|
|
@@ -237,19 +237,22 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements Sele
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
protected handleMoveRoutingPointsOnServer(target: SModelElement): Operation[] {
|
|
240
|
-
const result: Operation[] = [];
|
|
241
240
|
const newRoutingPoints: ElementAndRoutingPoints[] = [];
|
|
242
|
-
|
|
241
|
+
const routerRegistry = this.tool.edgeRouterRegistry;
|
|
242
|
+
if (routerRegistry) {
|
|
243
243
|
// If client routing is enabled -> delegate routingpoints of connected edges to server
|
|
244
|
-
|
|
245
|
-
element
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
244
|
+
forEachElement(target.index, isNonRoutableSelectedMovableBoundsAware, element => {
|
|
245
|
+
if (element instanceof SConnectableElement) {
|
|
246
|
+
element.incomingEdges.map(connectable => calcElementAndRoutingPoints(connectable, routerRegistry))
|
|
247
|
+
.forEach(ear => newRoutingPoints.push(ear));
|
|
248
|
+
element.outgoingEdges.map(connectable => calcElementAndRoutingPoints(connectable, routerRegistry))
|
|
249
|
+
.forEach(ear => newRoutingPoints.push(ear));
|
|
250
|
+
}
|
|
251
|
+
});
|
|
251
252
|
}
|
|
252
|
-
return
|
|
253
|
+
return newRoutingPoints.length > 0
|
|
254
|
+
? [ChangeRoutingPointsOperation.create(newRoutingPoints)]
|
|
255
|
+
: [];
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
protected handleResize(activeResizeHandle: SResizeHandle): Action[] {
|
|
@@ -18,6 +18,7 @@ import { ContainerModule, interfaces } from 'inversify';
|
|
|
18
18
|
import { configureActionHandler, configureModelElement } from 'sprotty';
|
|
19
19
|
import { FocusStateChangedAction } from '../../base/actions/focus-change-action';
|
|
20
20
|
import { TYPES } from '../../base/types';
|
|
21
|
+
import { GLSPSvgExporter } from '../export/glsp-svg-exporter';
|
|
21
22
|
import { MARQUEE } from '../tool-feedback/marquee-tool-feedback';
|
|
22
23
|
import { ChangeBoundsTool } from './change-bounds-tool';
|
|
23
24
|
import { DelKeyDeleteTool, MouseDeleteTool } from './delete-tool';
|
|
@@ -34,7 +35,7 @@ import { MarqueeView } from './view';
|
|
|
34
35
|
* Registers the default tools of GLSP (node and edge creation, changing bounds, edge editing, deletion)
|
|
35
36
|
* and adds the marquee selection tool.
|
|
36
37
|
*/
|
|
37
|
-
export const toolsModule = new ContainerModule((bind, _unbind, isBound) => {
|
|
38
|
+
export const toolsModule = new ContainerModule((bind, _unbind, isBound, rebind) => {
|
|
38
39
|
// Register default tools
|
|
39
40
|
bind(TYPES.IDefaultTool).to(ChangeBoundsTool);
|
|
40
41
|
bind(TYPES.IDefaultTool).to(EdgeEditTool);
|
|
@@ -50,6 +51,9 @@ export const toolsModule = new ContainerModule((bind, _unbind, isBound) => {
|
|
|
50
51
|
configureMarqueeTool({ bind, isBound });
|
|
51
52
|
configureActionHandler({ bind, isBound }, TriggerNodeCreationAction.KIND, NodeCreationTool);
|
|
52
53
|
configureActionHandler({ bind, isBound }, TriggerEdgeCreationAction.KIND, EdgeCreationTool);
|
|
54
|
+
|
|
55
|
+
bind(GLSPSvgExporter).toSelf().inSingletonScope();
|
|
56
|
+
rebind(TYPES.SvgExporter).toService(GLSPSvgExporter);
|
|
53
57
|
});
|
|
54
58
|
|
|
55
59
|
export function configureMarqueeTool(context: { bind: interfaces.Bind; isBound: interfaces.IsBound }): void {
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from 'sprotty';
|
|
32
32
|
import { DragAwareMouseListener } from '../../base/drag-aware-mouse-listener';
|
|
33
33
|
import { TYPES } from '../../base/types';
|
|
34
|
-
import { isRoutable, isRoutingHandle } from '../../utils/smodel-util';
|
|
34
|
+
import { calcElementAndRoutingPoints, isRoutable, isRoutingHandle } from '../../utils/smodel-util';
|
|
35
35
|
import { isReconnectable, isReconnectHandle, isSourceRoutingHandle, isTargetRoutingHandle, SReconnectHandle } from '../reconnect/model';
|
|
36
36
|
import { SelectionListener, SelectionService } from '../select/selection-service';
|
|
37
37
|
import { DrawFeedbackEdgeAction, feedbackEdgeId, RemoveFeedbackEdgeAction } from '../tool-feedback/creation-tool-feedback';
|
|
@@ -53,7 +53,7 @@ export class EdgeEditTool extends BaseGLSPTool {
|
|
|
53
53
|
|
|
54
54
|
@inject(TYPES.SelectionService) protected selectionService: SelectionService;
|
|
55
55
|
@inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry;
|
|
56
|
-
@inject(EdgeRouterRegistry) @optional()
|
|
56
|
+
@inject(EdgeRouterRegistry) @optional() readonly edgeRouterRegistry?: EdgeRouterRegistry;
|
|
57
57
|
@inject(TYPES.ISnapper) @optional() readonly snapper?: ISnapper;
|
|
58
58
|
|
|
59
59
|
protected feedbackEdgeSourceMovingListener: FeedbackEdgeSourceMovingMouseListener;
|
|
@@ -237,16 +237,15 @@ class EdgeEditListener extends DragAwareMouseListener implements SelectionListen
|
|
|
237
237
|
// reroute actions
|
|
238
238
|
const latestEdge = target.index.getById(this.edge.id);
|
|
239
239
|
if (latestEdge && isRoutable(latestEdge)) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
);
|
|
240
|
+
const newRoutingPoints = calcElementAndRoutingPoints(latestEdge, this.tool.edgeRouterRegistry);
|
|
241
|
+
result.push(ChangeRoutingPointsOperation.create([newRoutingPoints]));
|
|
243
242
|
this.routingHandle = undefined;
|
|
244
243
|
}
|
|
245
244
|
}
|
|
246
245
|
return result;
|
|
247
246
|
}
|
|
248
247
|
|
|
249
|
-
override mouseOver(target: SModelElement,
|
|
248
|
+
override mouseOver(target: SModelElement, _event: MouseEvent): Action[] {
|
|
250
249
|
if (this.edge && this.isReconnecting()) {
|
|
251
250
|
const currentTarget = findParentByFeature(target, isConnectable);
|
|
252
251
|
if (!this.newConnectable || currentTarget !== this.newConnectable) {
|
package/src/sprotty-reexport.ts
CHANGED
|
@@ -104,7 +104,12 @@ export {
|
|
|
104
104
|
export * from 'sprotty/lib/features/bounds/stack-layout';
|
|
105
105
|
export * from 'sprotty/lib/features/bounds/vbox-layout';
|
|
106
106
|
export * from 'sprotty/lib/features/bounds/views';
|
|
107
|
-
export
|
|
107
|
+
export {
|
|
108
|
+
ButtonHandlerRegistry,
|
|
109
|
+
configureButtonHandler,
|
|
110
|
+
IButtonHandler,
|
|
111
|
+
IButtonHandlerRegistration
|
|
112
|
+
} from 'sprotty/lib/features/button/button-handler';
|
|
108
113
|
export * from 'sprotty/lib/features/button/model';
|
|
109
114
|
export * from 'sprotty/lib/features/command-palette/action-providers';
|
|
110
115
|
export * from 'sprotty/lib/features/command-palette/command-palette';
|
package/src/utils/smodel-util.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { distinctAdd, ElementAndBounds, ElementAndRoutingPoints, remove, SModelElementSchema, TypeGuard } from '@eclipse-glsp/protocol';
|
|
17
17
|
import {
|
|
18
18
|
BoundsAware,
|
|
19
|
+
EdgeRouterRegistry,
|
|
19
20
|
isBoundsAware,
|
|
20
21
|
isMoveable,
|
|
21
22
|
isSelectable,
|
|
@@ -214,7 +215,7 @@ export function toElementAndBounds(element: BoundsAwareModelElement): ElementAnd
|
|
|
214
215
|
|
|
215
216
|
/**
|
|
216
217
|
* Helper function to translate a given {@link SRoutableElement} into its corresponding
|
|
217
|
-
* {@ElementAndRoutingPoints
|
|
218
|
+
* {@link ElementAndRoutingPoints} representation.
|
|
218
219
|
* @param element The element to translate.
|
|
219
220
|
* @returns The corresponding {@link ElementAndRoutingPoints} for the given element.
|
|
220
221
|
*/
|
|
@@ -225,6 +226,23 @@ export function toElementAndRoutingPoints(element: SRoutableElement): ElementAnd
|
|
|
225
226
|
};
|
|
226
227
|
}
|
|
227
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Helper function to calculate the {@link ElementAndRoutingPoints} for a given {@link SRoutableElement}.
|
|
231
|
+
* If client layout is activated, i.e., the edge routing registry is given and has a router for the element, then the routing
|
|
232
|
+
* points from the calculated route are used, otherwise we use the already specified routing points of the {@link SRoutableElement}.
|
|
233
|
+
* @param element The element to translate.
|
|
234
|
+
* @param edgeRouterRegistry the edge router registry
|
|
235
|
+
* @returns The corresponding {@link ElementAndRoutingPoints} for the given element.
|
|
236
|
+
*/
|
|
237
|
+
export function calcElementAndRoutingPoints(element: SRoutableElement, edgeRouterRegistry?: EdgeRouterRegistry): ElementAndRoutingPoints {
|
|
238
|
+
const router = edgeRouterRegistry?.get(element.routerKind);
|
|
239
|
+
// filter duplicate points (same x,y coordinates) and only keep actual routing points (no start or target, no volatile points)
|
|
240
|
+
const clientRoutingPoints = router?.route(element)
|
|
241
|
+
.filter((point, idx, route) => idx === route.findIndex(otherPoint => otherPoint.x === point.x && otherPoint.y === point.y))
|
|
242
|
+
.filter(point => point.kind === 'linear' || point.kind === 'bezier-junction');
|
|
243
|
+
return { elementId: element.id, newRoutingPoints: clientRoutingPoints || element.routingPoints };
|
|
244
|
+
}
|
|
245
|
+
|
|
228
246
|
/**
|
|
229
247
|
* Checks if the model is compatible with the passed type string.
|
|
230
248
|
* (either has the same type or a subtype of this type)
|
|
@@ -247,3 +265,4 @@ export function getElementTypeId(input: SModelElement | SModelElementSchema | st
|
|
|
247
265
|
return (input as any)['type'] as string;
|
|
248
266
|
}
|
|
249
267
|
}
|
|
268
|
+
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
ProjectedViewportView,
|
|
26
26
|
ProjectionParams,
|
|
27
27
|
RenderingContext,
|
|
28
|
+
setAttr,
|
|
28
29
|
setClass,
|
|
29
30
|
ViewportRootElement,
|
|
30
31
|
ViewProjection
|
|
@@ -36,12 +37,18 @@ import {
|
|
|
36
37
|
@injectable()
|
|
37
38
|
export class GLSPProjectionView extends ProjectedViewportView {
|
|
38
39
|
override render(model: Readonly<ViewportRootElement>, context: RenderingContext, args?: IViewArgs): VNode {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const svgElem = this.renderSvg(model, context, args);
|
|
41
|
+
if (svgElem.data) {
|
|
42
|
+
svgElem.data!.class = { 'sprotty-graph': true };
|
|
43
|
+
}
|
|
44
|
+
const rootNode: VNode = (
|
|
45
|
+
<div class-sprotty-graph={false} style={{ width: '100%', height: '100%' }}>
|
|
46
|
+
{svgElem}
|
|
42
47
|
{this.renderProjections(model, context, args)}
|
|
43
48
|
</div>
|
|
44
49
|
);
|
|
50
|
+
setAttr(rootNode, 'tabindex', 0);
|
|
51
|
+
return rootNode;
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
protected override renderSvg(model: Readonly<ViewportRootElement>, context: RenderingContext, args?: IViewArgs): VNode {
|