@eclipse-glsp/client 2.7.0-next.3 → 2.7.0
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/action-dispatcher.d.ts +2 -1
- package/lib/base/action-dispatcher.d.ts.map +1 -1
- package/lib/base/action-dispatcher.js +48 -24
- package/lib/base/action-dispatcher.js.map +1 -1
- package/lib/base/default.module.d.ts.map +1 -1
- package/lib/base/default.module.js +2 -0
- package/lib/base/default.module.js.map +1 -1
- package/lib/base/editor-context-service.d.ts +4 -3
- package/lib/base/editor-context-service.d.ts.map +1 -1
- package/lib/base/editor-context-service.js +11 -1
- package/lib/base/editor-context-service.js.map +1 -1
- package/lib/base/model/diagram-loader.d.ts +8 -6
- package/lib/base/model/diagram-loader.d.ts.map +1 -1
- package/lib/base/model/diagram-loader.js +1 -1
- package/lib/base/model/diagram-loader.js.map +1 -1
- package/lib/base/model/glsp-model-source.d.ts +5 -2
- package/lib/base/model/glsp-model-source.d.ts.map +1 -1
- package/lib/base/model/glsp-model-source.js +28 -1
- package/lib/base/model/glsp-model-source.js.map +1 -1
- package/lib/base/selection-service.d.ts +4 -3
- package/lib/base/selection-service.d.ts.map +1 -1
- package/lib/base/selection-service.js +6 -1
- package/lib/base/selection-service.js.map +1 -1
- package/lib/base/shortcuts/available-shortcuts-extension.d.ts +1 -1
- package/lib/base/shortcuts/available-shortcuts-extension.d.ts.map +1 -1
- package/lib/base/shortcuts/available-shortcuts-extension.js +3 -4
- package/lib/base/shortcuts/available-shortcuts-extension.js.map +1 -1
- package/lib/base/view/mouse-tool.d.ts +1 -1
- package/lib/base/view/mouse-tool.d.ts.map +1 -1
- package/lib/base/view/mouse-tool.js +3 -19
- package/lib/base/view/mouse-tool.js.map +1 -1
- package/lib/features/change-bounds/move-element-handler.d.ts +2 -3
- package/lib/features/change-bounds/move-element-handler.d.ts.map +1 -1
- package/lib/features/change-bounds/move-element-handler.js +2 -3
- package/lib/features/change-bounds/move-element-handler.js.map +1 -1
- package/lib/features/change-bounds/resize/resize-handler.d.ts +2 -3
- package/lib/features/change-bounds/resize/resize-handler.d.ts.map +1 -1
- package/lib/features/change-bounds/resize/resize-handler.js +2 -3
- package/lib/features/change-bounds/resize/resize-handler.js.map +1 -1
- package/lib/features/export/default-png-diagram-exporter.d.ts +52 -0
- package/lib/features/export/default-png-diagram-exporter.d.ts.map +1 -0
- package/lib/features/export/default-png-diagram-exporter.js +157 -0
- package/lib/features/export/default-png-diagram-exporter.js.map +1 -0
- package/lib/features/export/default-svg-diagram-exporter.d.ts +32 -0
- package/lib/features/export/default-svg-diagram-exporter.d.ts.map +1 -0
- package/lib/features/export/default-svg-diagram-exporter.js +54 -0
- package/lib/features/export/default-svg-diagram-exporter.js.map +1 -0
- package/lib/features/export/diagram-export-postprocessor.d.ts +33 -0
- package/lib/features/export/diagram-export-postprocessor.d.ts.map +1 -0
- package/lib/features/export/diagram-export-postprocessor.js +84 -0
- package/lib/features/export/diagram-export-postprocessor.js.map +1 -0
- package/lib/features/export/diagram-exporter.d.ts +44 -0
- package/lib/features/export/diagram-exporter.d.ts.map +1 -0
- package/lib/features/export/diagram-exporter.js +18 -0
- package/lib/features/export/diagram-exporter.js.map +1 -0
- package/lib/features/export/export-modules.d.ts +1 -1
- package/lib/features/export/export-modules.d.ts.map +1 -1
- package/lib/features/export/export-modules.js +20 -3
- package/lib/features/export/export-modules.js.map +1 -1
- package/lib/features/export/export-result-action-handler.d.ts +28 -0
- package/lib/features/export/export-result-action-handler.d.ts.map +1 -0
- package/lib/features/export/export-result-action-handler.js +72 -0
- package/lib/features/export/export-result-action-handler.js.map +1 -0
- package/lib/features/export/export-svg-action-handler.d.ts +19 -0
- package/lib/features/export/export-svg-action-handler.d.ts.map +1 -1
- package/lib/features/export/export-svg-action-handler.js +4 -15
- package/lib/features/export/export-svg-action-handler.js.map +1 -1
- package/lib/features/export/glsp-svg-exporter.d.ts +18 -1
- package/lib/features/export/glsp-svg-exporter.d.ts.map +1 -1
- package/lib/features/export/glsp-svg-exporter.js +44 -11
- package/lib/features/export/glsp-svg-exporter.js.map +1 -1
- package/lib/features/export/request-export-command.d.ts +29 -0
- package/lib/features/export/request-export-command.d.ts.map +1 -0
- package/lib/features/export/request-export-command.js +73 -0
- package/lib/features/export/request-export-command.js.map +1 -0
- package/lib/features/export/request-export-key-listener.d.ts +21 -0
- package/lib/features/export/request-export-key-listener.d.ts.map +1 -0
- package/lib/features/export/request-export-key-listener.js +40 -0
- package/lib/features/export/request-export-key-listener.js.map +1 -0
- package/lib/features/helper-lines/helper-line-feedback.d.ts +1 -1
- package/lib/features/helper-lines/helper-line-feedback.d.ts.map +1 -1
- package/lib/features/helper-lines/helper-line-feedback.js +2 -3
- package/lib/features/helper-lines/helper-line-feedback.js.map +1 -1
- package/lib/features/label-edit-ui/label-edit-ui.d.ts +1 -1
- package/lib/features/label-edit-ui/label-edit-ui.js +1 -1
- package/lib/features/routing/edge-router.d.ts +2 -1
- package/lib/features/routing/edge-router.d.ts.map +1 -1
- package/lib/features/routing/edge-router.js +2 -1
- package/lib/features/routing/edge-router.js.map +1 -1
- package/lib/features/routing/routing-module.d.ts +1 -1
- package/lib/features/routing/routing-module.d.ts.map +1 -1
- package/lib/features/routing/routing-module.js +7 -1
- package/lib/features/routing/routing-module.js.map +1 -1
- package/lib/features/routing/sticky-manhattan-anchors.d.ts +29 -0
- package/lib/features/routing/sticky-manhattan-anchors.d.ts.map +1 -0
- package/lib/features/routing/sticky-manhattan-anchors.js +62 -0
- package/lib/features/routing/sticky-manhattan-anchors.js.map +1 -0
- package/lib/features/routing/sticky-manhattan-edge-router.d.ts +107 -0
- package/lib/features/routing/sticky-manhattan-edge-router.d.ts.map +1 -0
- package/lib/features/routing/sticky-manhattan-edge-router.js +626 -0
- package/lib/features/routing/sticky-manhattan-edge-router.js.map +1 -0
- package/lib/features/search-palette/search-palette.d.ts +2 -2
- package/lib/features/search-palette/search-palette.d.ts.map +1 -1
- package/lib/features/search-palette/search-palette.js +3 -4
- package/lib/features/search-palette/search-palette.js.map +1 -1
- package/lib/features/select/select-module.d.ts +1 -1
- package/lib/features/select/select-module.js +1 -1
- package/lib/features/tool-palette/tool-palette.d.ts.map +1 -1
- package/lib/features/tool-palette/tool-palette.js +1 -2
- package/lib/features/tool-palette/tool-palette.js.map +1 -1
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts +2 -3
- 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 +2 -3
- package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js.map +1 -1
- package/lib/features/viewport/origin-viewport.d.ts +2 -13
- package/lib/features/viewport/origin-viewport.d.ts.map +1 -1
- package/lib/features/viewport/origin-viewport.js +3 -19
- package/lib/features/viewport/origin-viewport.js.map +1 -1
- package/lib/index.d.ts +11 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -1
- package/lib/index.js.map +1 -1
- package/lib/views/gedge-view-with-gaps-on-intersections.d.ts +39 -0
- package/lib/views/gedge-view-with-gaps-on-intersections.d.ts.map +1 -0
- package/lib/views/gedge-view-with-gaps-on-intersections.js +85 -0
- package/lib/views/gedge-view-with-gaps-on-intersections.js.map +1 -0
- package/lib/views/rounded-corner-manhattan-edge-view.d.ts +58 -0
- package/lib/views/rounded-corner-manhattan-edge-view.d.ts.map +1 -0
- package/lib/views/rounded-corner-manhattan-edge-view.js +170 -0
- package/lib/views/rounded-corner-manhattan-edge-view.js.map +1 -0
- package/package.json +4 -6
- package/src/base/action-dispatcher.spec.ts +103 -3
- package/src/base/action-dispatcher.ts +50 -25
- package/src/base/default.module.ts +4 -0
- package/src/base/editor-context-service.ts +17 -5
- package/src/base/model/diagram-loader.ts +8 -6
- package/src/base/model/glsp-model-source.ts +35 -1
- package/src/base/selection-service.ts +11 -2
- package/src/base/shortcuts/available-shortcuts-extension.ts +3 -4
- package/src/base/view/mouse-tool.ts +4 -19
- package/src/features/change-bounds/move-element-handler.ts +3 -2
- package/src/features/change-bounds/resize/resize-handler.ts +4 -3
- package/src/features/export/default-png-diagram-exporter.ts +145 -0
- package/src/features/export/default-svg-diagram-exporter.ts +39 -0
- package/src/features/export/diagram-export-postprocessor.ts +82 -0
- package/src/features/export/diagram-exporter.ts +45 -0
- package/src/features/export/export-modules.ts +24 -4
- package/src/features/export/export-result-action-handler.ts +66 -0
- package/src/features/export/export-svg-action-handler.ts +7 -2
- package/src/features/export/glsp-svg-exporter.ts +48 -12
- package/src/features/export/request-export-command.ts +65 -0
- package/src/features/export/request-export-key-listener.ts +29 -0
- package/src/features/helper-lines/helper-line-feedback.ts +6 -4
- package/src/features/label-edit-ui/label-edit-ui.ts +1 -1
- package/src/features/routing/edge-router.ts +2 -2
- package/src/features/routing/routing-module.ts +8 -1
- package/src/features/routing/sticky-manhattan-anchors.ts +53 -0
- package/src/features/routing/sticky-manhattan-edge-router.spec.ts +212 -0
- package/src/features/routing/sticky-manhattan-edge-router.ts +713 -0
- package/src/features/search-palette/search-palette.ts +3 -4
- package/src/features/select/select-module.ts +1 -1
- package/src/features/tool-palette/tool-palette.ts +1 -1
- package/src/features/tools/change-bounds/change-bounds-tool-move-feedback.ts +13 -3
- package/src/features/viewport/origin-viewport.ts +10 -23
- package/src/index.ts +11 -1
- package/src/views/gedge-view-with-gaps-on-intersections.tsx +99 -0
- package/src/views/rounded-corner-manhattan-edge-view.ts +171 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2023-
|
|
2
|
+
* Copyright (c) 2023-2026 Business Informatics Group (TU Wien) and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -14,9 +14,8 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import { GModelElement, GModelRoot, GNode, LabeledAction, SelectAllAction, toArray, TYPES } from '@eclipse-glsp/sprotty';
|
|
17
|
+
import { GModelElement, GModelRoot, GNode, LabeledAction, SelectAllAction, debounce, toArray, TYPES } from '@eclipse-glsp/sprotty';
|
|
18
18
|
import { inject, injectable } from 'inversify';
|
|
19
|
-
import { debounce, isEqual } from 'lodash';
|
|
20
19
|
import {
|
|
21
20
|
AutocompleteSuggestionProviderContext,
|
|
22
21
|
type AutocompleteSuggestion,
|
|
@@ -150,7 +149,7 @@ export class SearchAutocompletePalette extends BaseAutocompletePalette {
|
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
protected getSuggestionsFromLabeledActions(labeledActions: LabeledAction[]): SearchAutocompleteSuggestion[] {
|
|
153
|
-
return this.cachedSuggestions.filter(c => labeledActions.find(s =>
|
|
152
|
+
return this.cachedSuggestions.filter(c => labeledActions.find(s => s === c.action));
|
|
154
153
|
}
|
|
155
154
|
|
|
156
155
|
protected getHiddenElements(root: Readonly<GModelRoot>, suggestions: SearchAutocompleteSuggestion[]): GModelElement[] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2019-
|
|
2
|
+
* Copyright (c) 2019-2026 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
IActionHandler,
|
|
21
21
|
ICommand,
|
|
22
22
|
MarkersReason,
|
|
23
|
+
OriginViewportAction,
|
|
23
24
|
PaletteItem,
|
|
24
25
|
RequestContextActions,
|
|
25
26
|
RequestMarkersAction,
|
|
@@ -43,7 +44,6 @@ import { IDebugManager } from '../debug/debug-manager';
|
|
|
43
44
|
import { IGridManager } from '../grid/grid-manager';
|
|
44
45
|
import { MouseDeleteTool } from '../tools/deletion/delete-tool';
|
|
45
46
|
import { MarqueeMouseTool } from '../tools/marquee-selection/marquee-mouse-tool';
|
|
46
|
-
import { OriginViewportAction } from '../viewport/origin-viewport';
|
|
47
47
|
|
|
48
48
|
const CLICKED_CSS_CLASS = 'clicked';
|
|
49
49
|
const SEARCH_ICON_ID = 'search';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2019-
|
|
2
|
+
* Copyright (c) 2019-2026 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,9 +13,19 @@
|
|
|
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
|
+
DebouncedFunc,
|
|
19
|
+
ElementMove,
|
|
20
|
+
GModelElement,
|
|
21
|
+
GModelRoot,
|
|
22
|
+
MoveAction,
|
|
23
|
+
Point,
|
|
24
|
+
TypeGuard,
|
|
25
|
+
debounce,
|
|
26
|
+
findParentByFeature
|
|
27
|
+
} from '@eclipse-glsp/sprotty';
|
|
17
28
|
|
|
18
|
-
import { DebouncedFunc, debounce } from 'lodash';
|
|
19
29
|
import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
|
|
20
30
|
import { CursorCSS, cursorFeedbackAction } from '../../../base/feedback/css-feedback';
|
|
21
31
|
import { FeedbackEmitter } from '../../../base/feedback/feedback-emitter';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2024-
|
|
2
|
+
* Copyright (c) 2024-2026 Axon Ivy AG and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -14,31 +14,18 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Bounds,
|
|
19
|
+
BoundsAwareViewportCommand,
|
|
20
|
+
GModelRoot,
|
|
21
|
+
OriginViewportAction,
|
|
22
|
+
TYPES,
|
|
23
|
+
Viewport,
|
|
24
|
+
limitViewport
|
|
25
|
+
} from '@eclipse-glsp/sprotty';
|
|
18
26
|
import { inject, injectable } from 'inversify';
|
|
19
27
|
import { EditorContextService } from '../../base/editor-context-service';
|
|
20
28
|
|
|
21
|
-
export interface OriginViewportAction extends Action {
|
|
22
|
-
kind: typeof OriginViewportAction.KIND;
|
|
23
|
-
animate: boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export namespace OriginViewportAction {
|
|
27
|
-
export const KIND = 'originViewport';
|
|
28
|
-
|
|
29
|
-
export function is(object: any): object is OriginViewportAction {
|
|
30
|
-
return Action.hasKind(object, KIND);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function create(options: { animate?: boolean } = {}): OriginViewportAction {
|
|
34
|
-
return {
|
|
35
|
-
kind: KIND,
|
|
36
|
-
animate: true,
|
|
37
|
-
...options
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
29
|
@injectable()
|
|
43
30
|
export class OriginViewportCommand extends BoundsAwareViewportCommand {
|
|
44
31
|
static readonly KIND = OriginViewportAction.KIND;
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2024-
|
|
2
|
+
* Copyright (c) 2024-2026 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -132,9 +132,15 @@ export * from './features/element-template/add-template-element';
|
|
|
132
132
|
export * from './features/element-template/element-template-module';
|
|
133
133
|
export * from './features/element-template/mouse-tracking-element-position-listener';
|
|
134
134
|
export * from './features/element-template/remove-template-element';
|
|
135
|
+
export * from './features/export/default-png-diagram-exporter';
|
|
136
|
+
export * from './features/export/default-svg-diagram-exporter';
|
|
137
|
+
export * from './features/export/diagram-export-postprocessor';
|
|
138
|
+
export * from './features/export/diagram-exporter';
|
|
135
139
|
export * from './features/export/export-modules';
|
|
140
|
+
export * from './features/export/export-result-action-handler';
|
|
136
141
|
export * from './features/export/export-svg-action-handler';
|
|
137
142
|
export * from './features/export/glsp-svg-exporter';
|
|
143
|
+
export * from './features/export/request-export-command';
|
|
138
144
|
export * from './features/grid/grid';
|
|
139
145
|
export * from './features/grid/grid-manager';
|
|
140
146
|
export * from './features/grid/grid-model';
|
|
@@ -165,6 +171,8 @@ export * from './features/navigation/navigation-target-resolver';
|
|
|
165
171
|
export * from './features/reconnect/model';
|
|
166
172
|
export * from './features/routing/edge-router';
|
|
167
173
|
export * from './features/routing/routing-module';
|
|
174
|
+
export * from './features/routing/sticky-manhattan-anchors';
|
|
175
|
+
export * from './features/routing/sticky-manhattan-edge-router';
|
|
168
176
|
export * from './features/save/save-keylistener';
|
|
169
177
|
export * from './features/save/save-module';
|
|
170
178
|
export * from './features/search-palette/search-palette';
|
|
@@ -243,9 +251,11 @@ export * from './utils/viewpoint-util';
|
|
|
243
251
|
export * from './views/base-view-module';
|
|
244
252
|
export * from './views/compartments';
|
|
245
253
|
export * from './views/gedge-view';
|
|
254
|
+
export * from './views/gedge-view-with-gaps-on-intersections';
|
|
246
255
|
export * from './views/ggraph-view';
|
|
247
256
|
export * from './views/glsp-projection-view';
|
|
248
257
|
export * from './views/issue-marker-view';
|
|
249
258
|
export * from './views/rounded-corner';
|
|
259
|
+
export * from './views/rounded-corner-manhattan-edge-view';
|
|
250
260
|
export * from './views/rounded-corner-view';
|
|
251
261
|
export * from './views/routing-point-handle-view';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 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
|
+
/** @jsx svg */
|
|
17
|
+
import {
|
|
18
|
+
IViewArgs,
|
|
19
|
+
Point,
|
|
20
|
+
PolylineEdgeViewWithGapsOnIntersections,
|
|
21
|
+
RenderingContext,
|
|
22
|
+
isIntersectingRoutedPoint,
|
|
23
|
+
svg
|
|
24
|
+
} from '@eclipse-glsp/sprotty';
|
|
25
|
+
import { injectable } from 'inversify';
|
|
26
|
+
import { Classes, VNode } from 'snabbdom';
|
|
27
|
+
import { GEdge } from '../model';
|
|
28
|
+
import { EdgePadding } from '../utils/argument-utils';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Gap-rendering counterpart to {@link GEdgeView}: extends
|
|
32
|
+
* {@link PolylineEdgeViewWithGapsOnIntersections} and re-adds the GLSP-only
|
|
33
|
+
* bits from `GEdgeView` — router dispatch, dangling-edge rendering,
|
|
34
|
+
* `additionalClasses` hook, and the edge-padding mouse-handle overlay.
|
|
35
|
+
*
|
|
36
|
+
* Subclasses override {@link createPathForSegments} to inject per-point path
|
|
37
|
+
* fragments. Intersections are spliced into the rendered line
|
|
38
|
+
* (`addIntersectionPoints = true`) and skipped for the mouse-handle overlay
|
|
39
|
+
* so the hit area stays contiguous.
|
|
40
|
+
*/
|
|
41
|
+
@injectable()
|
|
42
|
+
export class GEdgeViewWithGapsOnIntersections extends PolylineEdgeViewWithGapsOnIntersections {
|
|
43
|
+
override render(edge: Readonly<GEdge>, context: RenderingContext, args?: IViewArgs): VNode {
|
|
44
|
+
// route(edge, args) picks up the postprocessed routing populated by
|
|
45
|
+
// SGraphView — that's where IntersectionFinder tags points.
|
|
46
|
+
const route = this.edgeRouterRegistry.route(edge, args);
|
|
47
|
+
if (route.length === 0) {
|
|
48
|
+
return this.renderDanglingEdge('Cannot compute route', edge, context);
|
|
49
|
+
}
|
|
50
|
+
return (
|
|
51
|
+
<g class-sprotty-edge={true} class-mouseover={edge.hoverFeedback} {...this.additionalClasses(edge, context)}>
|
|
52
|
+
{this.renderLine(edge, route, context, args)}
|
|
53
|
+
{this.renderAdditionals(edge, route, context)}
|
|
54
|
+
{context.renderChildren(edge, { route })}
|
|
55
|
+
</g>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected additionalClasses(_edge: Readonly<GEdge>, _context: RenderingContext): Classes {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected override renderLine(edge: GEdge, segments: Point[], _context: RenderingContext, args?: IViewArgs): VNode {
|
|
64
|
+
return <path d={this.createPathForSegments(segments, edge, true, args)} />;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected override renderAdditionals(edge: GEdge, segments: Point[], _context: RenderingContext): VNode[] {
|
|
68
|
+
const edgePadding = EdgePadding.from(edge);
|
|
69
|
+
return edgePadding ? [this.renderMouseHandle(edge, segments, edgePadding)] : [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected renderMouseHandle(edge: GEdge, segments: Point[], padding: number): VNode {
|
|
73
|
+
return (
|
|
74
|
+
<path
|
|
75
|
+
class-mouse-handle
|
|
76
|
+
d={this.createPathForSegments(segments, edge, false)}
|
|
77
|
+
style-stroke-width={padding * 2}
|
|
78
|
+
style-stroke='transparent'
|
|
79
|
+
style-stroke-dasharray='none'
|
|
80
|
+
style-stroke-dashoffset='0'
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
protected createPathForSegments(segments: Point[], edge: GEdge, addIntersectionPoints: boolean, args?: IViewArgs): string {
|
|
86
|
+
if (segments.length === 0) {
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
let path = `M ${segments[0].x},${segments[0].y}`;
|
|
90
|
+
for (let i = 1; i < segments.length; i++) {
|
|
91
|
+
const p = segments[i];
|
|
92
|
+
if (addIntersectionPoints && isIntersectingRoutedPoint(p)) {
|
|
93
|
+
path += this.intersectionPath(edge, segments, p, args);
|
|
94
|
+
}
|
|
95
|
+
path += ` L ${p.x},${p.y}`;
|
|
96
|
+
}
|
|
97
|
+
return path;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2022-2026 Imixs Software Solutions GmbH.
|
|
3
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
4
|
+
*
|
|
5
|
+
* This program and the accompanying materials are made available under the
|
|
6
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
*
|
|
9
|
+
* This Source Code may also be made available under the following Secondary
|
|
10
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
* with the GNU Classpath Exception which is available at
|
|
13
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
16
|
+
********************************************************************************/
|
|
17
|
+
import { IntersectingRoutedPoint, IViewArgs, Point, isIntersectingRoutedPoint } from '@eclipse-glsp/sprotty';
|
|
18
|
+
import { injectable } from 'inversify';
|
|
19
|
+
import { GEdge } from '../model';
|
|
20
|
+
import { GEdgeViewWithGapsOnIntersections } from './gedge-view-with-gaps-on-intersections';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Manhattan edge view with rounded bends rendered as quadratic Béziers.
|
|
24
|
+
* Non-orthogonal inputs render as sharp corners. Radius is clamped per corner;
|
|
25
|
+
* override {@link cornerRadius} or {@link computeMaxRadius} to tune.
|
|
26
|
+
*
|
|
27
|
+
* Inherits gap / line-jump rendering from {@link GEdgeViewWithGapsOnIntersections}.
|
|
28
|
+
* The rendered line splices intersection fragments between points; the mouse-
|
|
29
|
+
* handle overlay skips them so the hit area stays contiguous.
|
|
30
|
+
*
|
|
31
|
+
* Based on Ralph Soika's `BPMNEdgeView`; see
|
|
32
|
+
* https://github.com/eclipse-glsp/glsp/discussions/1642.
|
|
33
|
+
*/
|
|
34
|
+
@injectable()
|
|
35
|
+
export class RoundedCornerManhattanEdgeView extends GEdgeViewWithGapsOnIntersections {
|
|
36
|
+
/** Target corner radius in pixels. The effective radius is clamped per corner. */
|
|
37
|
+
protected readonly cornerRadius: number = 10;
|
|
38
|
+
|
|
39
|
+
/** Lower bound for the effective radius, even on very short adjacent segments. */
|
|
40
|
+
protected readonly minCornerRadius: number = 2;
|
|
41
|
+
|
|
42
|
+
/** Upper fraction of the shorter adjacent segment to use for the radius. */
|
|
43
|
+
protected readonly maxRadiusFactor: number = 0.45;
|
|
44
|
+
|
|
45
|
+
/** Segment length (px) below which {@link shortSegmentRadiusFactor} tightens the radius further. */
|
|
46
|
+
protected readonly shortSegmentThreshold: number = 5;
|
|
47
|
+
|
|
48
|
+
/** Fraction of the shorter adjacent segment to use as the radius below {@link shortSegmentThreshold}. */
|
|
49
|
+
protected readonly shortSegmentRadiusFactor: number = 0.3;
|
|
50
|
+
|
|
51
|
+
protected override createPathForSegments(segments: Point[], edge: GEdge, addIntersectionPoints: boolean, args?: IViewArgs): string {
|
|
52
|
+
if (segments.length === 0) {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
let path = `M ${segments[0].x},${segments[0].y}`;
|
|
56
|
+
for (let i = 1; i < segments.length; i++) {
|
|
57
|
+
const p = segments[i];
|
|
58
|
+
if (addIntersectionPoints && isIntersectingRoutedPoint(p)) {
|
|
59
|
+
const effective = this.filterCornerZoneIntersections(p, segments, i);
|
|
60
|
+
if (effective.intersections.length > 0) {
|
|
61
|
+
path += this.intersectionPath(edge, segments, effective, args);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (i < segments.length - 1) {
|
|
65
|
+
const prev = segments[i - 1];
|
|
66
|
+
const next = segments[i + 1];
|
|
67
|
+
const radius = this.computeMaxRadius(p, prev, next);
|
|
68
|
+
path += this.renderRoundedCorner(p, prev, next, radius);
|
|
69
|
+
} else {
|
|
70
|
+
path += ` L ${p.x},${p.y}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return path;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Drops intersections inside either endpoint's rounded-corner zone (padded
|
|
78
|
+
* by the gap's skip-offset). The gap fragment can't be placed there without
|
|
79
|
+
* drawing backward into the curve on one side, and the crossing is hidden
|
|
80
|
+
* behind the curve anyway.
|
|
81
|
+
*/
|
|
82
|
+
protected filterCornerZoneIntersections(
|
|
83
|
+
intersectingPoint: IntersectingRoutedPoint,
|
|
84
|
+
segments: Point[],
|
|
85
|
+
pointIndex: number
|
|
86
|
+
): IntersectingRoutedPoint {
|
|
87
|
+
const p1 = segments[pointIndex - 1];
|
|
88
|
+
const p2 = segments[pointIndex];
|
|
89
|
+
const p1Threshold = this.getCornerRadius(segments, pointIndex - 1) + this.skipOffsetBefore;
|
|
90
|
+
const p2Threshold = this.getCornerRadius(segments, pointIndex) + this.skipOffsetAfter;
|
|
91
|
+
const filtered = intersectingPoint.intersections.filter(
|
|
92
|
+
intersection =>
|
|
93
|
+
Point.maxDistance(intersection.intersectionPoint, p1) > p1Threshold &&
|
|
94
|
+
Point.maxDistance(intersection.intersectionPoint, p2) > p2Threshold
|
|
95
|
+
);
|
|
96
|
+
return { ...intersectingPoint, intersections: filtered };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Curve radius at `segments[cornerIndex]`, or 0 for source / target. */
|
|
100
|
+
protected getCornerRadius(segments: Point[], cornerIndex: number): number {
|
|
101
|
+
if (cornerIndex <= 0 || cornerIndex >= segments.length - 1) {
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
const corner = segments[cornerIndex];
|
|
105
|
+
const prev = segments[cornerIndex - 1];
|
|
106
|
+
const next = segments[cornerIndex + 1];
|
|
107
|
+
return this.computeMaxRadius(corner, prev, next);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** SVG fragment for one rounded corner; falls back to `L` if not a right angle. */
|
|
111
|
+
protected renderRoundedCorner(corner: Point, prev: Point, next: Point, radius: number): string {
|
|
112
|
+
// Round only right-angle bends; diagonal / collinear inputs render sharp.
|
|
113
|
+
const horizIn = Point.isHorizontalAligned(prev, corner);
|
|
114
|
+
const vertIn = Point.isVerticalAligned(prev, corner);
|
|
115
|
+
const horizOut = Point.isHorizontalAligned(corner, next);
|
|
116
|
+
const vertOut = Point.isVerticalAligned(corner, next);
|
|
117
|
+
const isRightAngle = (horizIn && vertOut && !vertIn) || (vertIn && horizOut && !horizIn);
|
|
118
|
+
if (!isRightAngle) {
|
|
119
|
+
return ` L ${corner.x},${corner.y}`;
|
|
120
|
+
}
|
|
121
|
+
if (prev.x < corner.x && corner.y < next.y) {
|
|
122
|
+
// right → down
|
|
123
|
+
return ` L ${corner.x - radius},${corner.y} Q ${corner.x},${corner.y} ${corner.x},${corner.y + radius}`;
|
|
124
|
+
}
|
|
125
|
+
if (prev.y < corner.y && corner.x < next.x) {
|
|
126
|
+
// down → right
|
|
127
|
+
return ` L ${corner.x},${corner.y - radius} Q ${corner.x},${corner.y} ${corner.x + radius},${corner.y}`;
|
|
128
|
+
}
|
|
129
|
+
if (prev.x < corner.x && corner.y > next.y) {
|
|
130
|
+
// right → up
|
|
131
|
+
return ` L ${corner.x - radius},${corner.y} Q ${corner.x},${corner.y} ${corner.x},${corner.y - radius}`;
|
|
132
|
+
}
|
|
133
|
+
if (prev.y > corner.y && corner.x < next.x) {
|
|
134
|
+
// up → right
|
|
135
|
+
return ` L ${corner.x},${corner.y + radius} Q ${corner.x},${corner.y} ${corner.x + radius},${corner.y}`;
|
|
136
|
+
}
|
|
137
|
+
if (prev.y < corner.y && corner.x > next.x) {
|
|
138
|
+
// down → left
|
|
139
|
+
return ` L ${corner.x},${corner.y - radius} Q ${corner.x},${corner.y} ${corner.x - radius},${corner.y}`;
|
|
140
|
+
}
|
|
141
|
+
if (prev.x > corner.x && corner.y < next.y) {
|
|
142
|
+
// left → down
|
|
143
|
+
return ` L ${corner.x + radius},${corner.y} Q ${corner.x},${corner.y} ${corner.x},${corner.y + radius}`;
|
|
144
|
+
}
|
|
145
|
+
if (prev.y > corner.y && corner.x > next.x) {
|
|
146
|
+
// up → left
|
|
147
|
+
return ` L ${corner.x},${corner.y + radius} Q ${corner.x},${corner.y} ${corner.x - radius},${corner.y}`;
|
|
148
|
+
}
|
|
149
|
+
if (prev.x > corner.x && corner.y > next.y) {
|
|
150
|
+
// left → up
|
|
151
|
+
return ` L ${corner.x + radius},${corner.y} Q ${corner.x},${corner.y} ${corner.x},${corner.y - radius}`;
|
|
152
|
+
}
|
|
153
|
+
return ` L ${corner.x},${corner.y}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Clamps {@link cornerRadius} to a fraction of the shorter adjacent segment. */
|
|
157
|
+
protected computeMaxRadius(corner: Point, prev: Point, next: Point): number {
|
|
158
|
+
const segBefore = Point.maxDistance(corner, prev);
|
|
159
|
+
const segAfter = Point.maxDistance(next, corner);
|
|
160
|
+
if (segBefore === 0 || segAfter === 0) {
|
|
161
|
+
return this.minCornerRadius;
|
|
162
|
+
}
|
|
163
|
+
const shortest = Math.min(segBefore, segAfter);
|
|
164
|
+
let radius = Math.min(this.cornerRadius, shortest * this.maxRadiusFactor);
|
|
165
|
+
if (shortest < this.shortSegmentThreshold) {
|
|
166
|
+
radius = Math.min(radius, shortest * this.shortSegmentRadiusFactor);
|
|
167
|
+
}
|
|
168
|
+
radius = Math.min(radius, shortest / 2);
|
|
169
|
+
return Math.max(this.minCornerRadius, radius);
|
|
170
|
+
}
|
|
171
|
+
}
|