@eclipse-glsp/client 2.2.0-next.336 → 2.2.0-next.337

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.
Files changed (169) hide show
  1. package/css/ghost-element.css +7 -0
  2. package/lib/base/default.module.d.ts.map +1 -1
  3. package/lib/base/default.module.js +1 -2
  4. package/lib/base/default.module.js.map +1 -1
  5. package/lib/base/drag-aware-mouse-listener.d.ts +4 -1
  6. package/lib/base/drag-aware-mouse-listener.d.ts.map +1 -1
  7. package/lib/base/drag-aware-mouse-listener.js +12 -2
  8. package/lib/base/drag-aware-mouse-listener.js.map +1 -1
  9. package/lib/base/feedback/feedback-action-dispatcher-default.d.ts +34 -0
  10. package/lib/base/feedback/feedback-action-dispatcher-default.d.ts.map +1 -0
  11. package/lib/base/feedback/feedback-action-dispatcher-default.js +120 -0
  12. package/lib/base/feedback/feedback-action-dispatcher-default.js.map +1 -0
  13. package/lib/base/feedback/feedback-action-dispatcher.d.ts +2 -17
  14. package/lib/base/feedback/feedback-action-dispatcher.d.ts.map +1 -1
  15. package/lib/base/feedback/feedback-action-dispatcher.js +1 -100
  16. package/lib/base/feedback/feedback-action-dispatcher.js.map +1 -1
  17. package/lib/base/feedback/{feeback-emitter.d.ts → feedback-emitter.d.ts} +8 -1
  18. package/lib/base/feedback/feedback-emitter.d.ts.map +1 -0
  19. package/lib/base/feedback/{feeback-emitter.js → feedback-emitter.js} +21 -6
  20. package/lib/base/feedback/feedback-emitter.js.map +1 -0
  21. package/lib/base/feedback/index.d.ts +2 -1
  22. package/lib/base/feedback/index.d.ts.map +1 -1
  23. package/lib/base/feedback/index.js +2 -1
  24. package/lib/base/feedback/index.js.map +1 -1
  25. package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts.map +1 -1
  26. package/lib/features/accessibility/view-key-tools/movement-key-tool.js +1 -1
  27. package/lib/features/accessibility/view-key-tools/movement-key-tool.js.map +1 -1
  28. package/lib/features/change-bounds/model.d.ts +5 -1
  29. package/lib/features/change-bounds/model.d.ts.map +1 -1
  30. package/lib/features/change-bounds/model.js +36 -10
  31. package/lib/features/change-bounds/model.js.map +1 -1
  32. package/lib/features/change-bounds/movement-restrictor.d.ts +1 -0
  33. package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
  34. package/lib/features/change-bounds/movement-restrictor.js +8 -9
  35. package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
  36. package/lib/features/debug/debug-bounds-decorator.d.ts.map +1 -1
  37. package/lib/features/debug/debug-bounds-decorator.js +6 -6
  38. package/lib/features/debug/debug-bounds-decorator.js.map +1 -1
  39. package/lib/features/debug/debug-module.js +1 -1
  40. package/lib/features/debug/debug-module.js.map +1 -1
  41. package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts +6 -4
  42. package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts.map +1 -1
  43. package/lib/features/element-template/mouse-tracking-element-position-listener.js +11 -12
  44. package/lib/features/element-template/mouse-tracking-element-position-listener.js.map +1 -1
  45. package/lib/features/grid/grid-module.d.ts.map +1 -1
  46. package/lib/features/grid/grid-module.js +1 -1
  47. package/lib/features/grid/grid-module.js.map +1 -1
  48. package/lib/features/helper-lines/helper-line-manager-default.d.ts +14 -2
  49. package/lib/features/helper-lines/helper-line-manager-default.d.ts.map +1 -1
  50. package/lib/features/helper-lines/helper-line-manager-default.js +56 -15
  51. package/lib/features/helper-lines/helper-line-manager-default.js.map +1 -1
  52. package/lib/features/hints/model.d.ts +5 -1
  53. package/lib/features/hints/model.d.ts.map +1 -1
  54. package/lib/features/hints/model.js.map +1 -1
  55. package/lib/features/select/select-mouse-listener.d.ts.map +1 -1
  56. package/lib/features/select/select-mouse-listener.js +1 -1
  57. package/lib/features/select/select-mouse-listener.js.map +1 -1
  58. package/lib/features/tool-palette/tool-palette.d.ts.map +1 -1
  59. package/lib/features/tool-palette/tool-palette.js +2 -2
  60. package/lib/features/tool-palette/tool-palette.js.map +1 -1
  61. package/lib/features/tools/base-tools.d.ts +1 -1
  62. package/lib/features/tools/base-tools.d.ts.map +1 -1
  63. package/lib/features/tools/change-bounds/change-bounds-manager.d.ts +11 -4
  64. package/lib/features/tools/change-bounds/change-bounds-manager.d.ts.map +1 -1
  65. package/lib/features/tools/change-bounds/change-bounds-manager.js +46 -13
  66. package/lib/features/tools/change-bounds/change-bounds-manager.js.map +1 -1
  67. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts.map +1 -1
  68. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js +3 -3
  69. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js.map +1 -1
  70. package/lib/features/tools/change-bounds/change-bounds-tool-module.js +1 -1
  71. package/lib/features/tools/change-bounds/change-bounds-tool-module.js.map +1 -1
  72. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts +2 -2
  73. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts.map +1 -1
  74. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js +3 -6
  75. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js.map +1 -1
  76. package/lib/features/tools/change-bounds/change-bounds-tool.d.ts +3 -2
  77. package/lib/features/tools/change-bounds/change-bounds-tool.d.ts.map +1 -1
  78. package/lib/features/tools/change-bounds/change-bounds-tool.js +7 -27
  79. package/lib/features/tools/change-bounds/change-bounds-tool.js.map +1 -1
  80. package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts +8 -2
  81. package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts.map +1 -1
  82. package/lib/features/tools/change-bounds/change-bounds-tracker.js +22 -5
  83. package/lib/features/tools/change-bounds/change-bounds-tracker.js.map +1 -1
  84. package/lib/features/tools/edge-creation/edge-creation-tool.d.ts +4 -1
  85. package/lib/features/tools/edge-creation/edge-creation-tool.d.ts.map +1 -1
  86. package/lib/features/tools/edge-creation/edge-creation-tool.js +12 -10
  87. package/lib/features/tools/edge-creation/edge-creation-tool.js.map +1 -1
  88. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts +1 -1
  89. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts.map +1 -1
  90. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js +3 -3
  91. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js.map +1 -1
  92. package/lib/features/tools/edge-edit/edge-edit-tool.d.ts +1 -1
  93. package/lib/features/tools/edge-edit/edge-edit-tool.d.ts.map +1 -1
  94. package/lib/features/tools/edge-edit/edge-edit-tool.js +3 -3
  95. package/lib/features/tools/edge-edit/edge-edit-tool.js.map +1 -1
  96. package/lib/features/tools/node-creation/container-manager.d.ts +41 -0
  97. package/lib/features/tools/node-creation/container-manager.d.ts.map +1 -0
  98. package/lib/features/tools/node-creation/container-manager.js +73 -0
  99. package/lib/features/tools/node-creation/container-manager.js.map +1 -0
  100. package/lib/features/tools/node-creation/index.d.ts +3 -0
  101. package/lib/features/tools/node-creation/index.d.ts.map +1 -1
  102. package/lib/features/tools/node-creation/index.js +3 -0
  103. package/lib/features/tools/node-creation/index.js.map +1 -1
  104. package/lib/features/tools/node-creation/insert-indicator.d.ts +30 -0
  105. package/lib/features/tools/node-creation/insert-indicator.d.ts.map +1 -0
  106. package/lib/features/tools/node-creation/insert-indicator.js +40 -0
  107. package/lib/features/tools/node-creation/insert-indicator.js.map +1 -0
  108. package/lib/features/tools/node-creation/node-creation-module.d.ts.map +1 -1
  109. package/lib/features/tools/node-creation/node-creation-module.js +5 -0
  110. package/lib/features/tools/node-creation/node-creation-module.js.map +1 -1
  111. package/lib/features/tools/node-creation/node-creation-tool.d.ts +23 -14
  112. package/lib/features/tools/node-creation/node-creation-tool.d.ts.map +1 -1
  113. package/lib/features/tools/node-creation/node-creation-tool.js +79 -75
  114. package/lib/features/tools/node-creation/node-creation-tool.js.map +1 -1
  115. package/lib/features/tools/node-creation/node-creation-views.d.ts +25 -0
  116. package/lib/features/tools/node-creation/node-creation-views.d.ts.map +1 -0
  117. package/lib/features/tools/node-creation/node-creation-views.js +60 -0
  118. package/lib/features/tools/node-creation/node-creation-views.js.map +1 -0
  119. package/lib/utils/gmodel-util.d.ts +2 -0
  120. package/lib/utils/gmodel-util.d.ts.map +1 -1
  121. package/lib/utils/gmodel-util.js.map +1 -1
  122. package/lib/views/ggraph-view.d.ts.map +1 -1
  123. package/lib/views/ggraph-view.js +2 -2
  124. package/lib/views/ggraph-view.js.map +1 -1
  125. package/lib/views/glsp-projection-view.d.ts.map +1 -1
  126. package/lib/views/glsp-projection-view.js +2 -2
  127. package/lib/views/glsp-projection-view.js.map +1 -1
  128. package/package.json +3 -3
  129. package/src/base/default.module.ts +1 -2
  130. package/src/base/drag-aware-mouse-listener.ts +17 -1
  131. package/src/base/feedback/feedback-action-dispatcher-default.ts +119 -0
  132. package/src/base/feedback/feedback-action-dispatcher.ts +2 -106
  133. package/src/base/feedback/feedback-emitter.spec.ts +176 -0
  134. package/src/base/feedback/{feeback-emitter.ts → feedback-emitter.ts} +24 -5
  135. package/src/base/feedback/index.ts +2 -1
  136. package/src/base/selection-service.spec.ts +1 -1
  137. package/src/features/accessibility/view-key-tools/movement-key-tool.ts +1 -1
  138. package/src/features/change-bounds/model.ts +38 -13
  139. package/src/features/change-bounds/movement-restrictor.ts +11 -11
  140. package/src/features/debug/debug-bounds-decorator.tsx +7 -7
  141. package/src/features/debug/debug-module.ts +1 -1
  142. package/src/features/element-template/mouse-tracking-element-position-listener.ts +14 -22
  143. package/src/features/grid/grid-module.ts +2 -2
  144. package/src/features/helper-lines/helper-line-manager-default.ts +66 -10
  145. package/src/features/hints/model.ts +6 -1
  146. package/src/features/hints/type-hint-provider.spec.ts +1 -1
  147. package/src/features/select/select-mouse-listener.ts +2 -2
  148. package/src/features/tool-palette/tool-palette.ts +2 -3
  149. package/src/features/tools/base-tools.ts +1 -1
  150. package/src/features/tools/change-bounds/change-bounds-manager.ts +71 -13
  151. package/src/features/tools/change-bounds/change-bounds-tool-feedback.ts +5 -2
  152. package/src/features/tools/change-bounds/change-bounds-tool-module.ts +1 -1
  153. package/src/features/tools/change-bounds/change-bounds-tool-move-feedback.ts +4 -8
  154. package/src/features/tools/change-bounds/change-bounds-tool.ts +9 -55
  155. package/src/features/tools/change-bounds/change-bounds-tracker.ts +26 -5
  156. package/src/features/tools/edge-creation/edge-creation-tool.ts +13 -6
  157. package/src/features/tools/edge-edit/edge-edit-tool-feedback.ts +1 -1
  158. package/src/features/tools/edge-edit/edge-edit-tool.ts +2 -3
  159. package/src/features/tools/node-creation/container-manager.ts +76 -0
  160. package/src/features/tools/node-creation/index.ts +3 -0
  161. package/src/features/tools/node-creation/insert-indicator.ts +41 -0
  162. package/src/features/tools/node-creation/node-creation-module.ts +13 -1
  163. package/src/features/tools/node-creation/node-creation-tool.ts +98 -90
  164. package/src/features/tools/node-creation/node-creation-views.tsx +49 -0
  165. package/src/utils/gmodel-util.ts +4 -1
  166. package/src/views/ggraph-view.tsx +3 -3
  167. package/src/views/glsp-projection-view.tsx +2 -3
  168. package/lib/base/feedback/feeback-emitter.d.ts.map +0 -1
  169. package/lib/base/feedback/feeback-emitter.js.map +0 -1
@@ -37,17 +37,8 @@ import {
37
37
  TYPES,
38
38
  findParentByFeature
39
39
  } from '@eclipse-glsp/sprotty';
40
- import { CSS_RESIZE_MODE, ChangeBoundsManager, ChangeBoundsTracker, TrackedElementResize, TrackedResize } from '..';
41
40
  import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
42
- import {
43
- CursorCSS,
44
- ModifyCSSFeedbackAction,
45
- applyCssClasses,
46
- cursorFeedbackAction,
47
- deleteCssClasses,
48
- toggleCssClasses
49
- } from '../../../base/feedback/css-feedback';
50
- import { FeedbackEmitter } from '../../../base/feedback/feeback-emitter';
41
+ import { FeedbackEmitter } from '../../../base/feedback/feedback-emitter';
51
42
  import { ISelectionListener, SelectionService } from '../../../base/selection-service';
52
43
  import {
53
44
  BoundsAwareModelElement,
@@ -60,18 +51,16 @@ import {
60
51
  } from '../../../utils/gmodel-util';
61
52
  import { LocalRequestBoundsAction, SetBoundsFeedbackAction } from '../../bounds';
62
53
  import { SResizeHandle, isResizable } from '../../change-bounds/model';
63
- import {
64
- IMovementRestrictor,
65
- movementRestrictionFeedback,
66
- removeMovementRestrictionFeedback
67
- } from '../../change-bounds/movement-restrictor';
54
+ import { IMovementRestrictor } from '../../change-bounds/movement-restrictor';
68
55
  import { BaseEditTool } from '../base-tools';
56
+ import { CSS_ACTIVE_HANDLE, ChangeBoundsManager } from './change-bounds-manager';
69
57
  import {
70
58
  HideChangeBoundsToolResizeFeedbackAction,
71
59
  MoveFinishedEventAction,
72
60
  ShowChangeBoundsToolResizeFeedbackAction
73
61
  } from './change-bounds-tool-feedback';
74
62
  import { FeedbackMoveMouseListener } from './change-bounds-tool-move-feedback';
63
+ import { ChangeBoundsTracker, TrackedElementResize, TrackedResize } from './change-bounds-tracker';
75
64
 
76
65
  /**
77
66
  * The change bounds tool has the license to move multiple elements or resize a single element by implementing the ChangeBounds operation.
@@ -93,7 +82,7 @@ export class ChangeBoundsTool extends BaseEditTool {
93
82
  @inject(SelectionService) protected selectionService: SelectionService;
94
83
  @inject(EdgeRouterRegistry) @optional() readonly edgeRouterRegistry?: EdgeRouterRegistry;
95
84
  @inject(TYPES.IMovementRestrictor) @optional() readonly movementRestrictor?: IMovementRestrictor;
96
- @inject(TYPES.IChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
85
+ @inject(ChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
97
86
 
98
87
  get id(): string {
99
88
  return ChangeBoundsTool.ID;
@@ -133,7 +122,7 @@ export class ChangeBoundsTool extends BaseEditTool {
133
122
  }
134
123
 
135
124
  export class ChangeBoundsListener extends DragAwareMouseListener implements ISelectionListener {
136
- static readonly CSS_CLASS_ACTIVE = 'active';
125
+ static readonly CSS_CLASS_ACTIVE = CSS_ACTIVE_HANDLE;
137
126
 
138
127
  // members for calculating the correct position change
139
128
  protected initialBounds: ElementAndBounds | undefined;
@@ -206,15 +195,13 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
206
195
  // consider resize handles ourselves
207
196
  if (this.activeResizeHandle && this.tracker.isTracking()) {
208
197
  const resize = this.tracker.resizeElements(this.activeResizeHandle, { snap: event, symmetric: event, restrict: event });
209
- this.addResizeFeedback(resize, target, event);
210
198
  const resizeAction = this.resizeBoundsAction(resize);
211
199
  if (resizeAction.bounds.length > 0) {
212
200
  this.resizeFeedback.add(resizeAction, () => this.resetBounds());
213
201
  this.tracker.updateTrackingPosition(resize.handleMove.moveVector);
214
- } else {
215
- this.resizeFeedback.add(undefined, () => this.resetBounds());
202
+ this.addResizeFeedback(resize, target, event);
203
+ this.resizeFeedback.submit();
216
204
  }
217
- this.resizeFeedback.submit();
218
205
  }
219
206
  return super.draggingMouseMove(target, event);
220
207
  }
@@ -234,40 +221,7 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
234
221
  }
235
222
 
236
223
  protected addResizeFeedback(resize: TrackedResize, target: GModelElement, event: MouseEvent): void {
237
- const handle = resize.handleMove.element;
238
- // handle feedback
239
- this.resizeFeedback.add(
240
- applyCssClasses(handle, ChangeBoundsListener.CSS_CLASS_ACTIVE),
241
- deleteCssClasses(handle, ChangeBoundsListener.CSS_CLASS_ACTIVE)
242
- );
243
-
244
- // graph feedback
245
- this.resizeFeedback.add(
246
- ModifyCSSFeedbackAction.create({ add: [CSS_RESIZE_MODE] }),
247
- ModifyCSSFeedbackAction.create({ remove: [CSS_RESIZE_MODE] })
248
- );
249
-
250
- // cursor feedback
251
- const cursorClass = SResizeHandle.getCursorCss(resize.handleMove.element);
252
- this.resizeFeedback.add(cursorFeedbackAction(cursorClass), cursorFeedbackAction(CursorCSS.DEFAULT));
253
-
254
- const movementRestrictor = this.tool.changeBoundsManager.movementRestrictor;
255
- resize.elementResizes.forEach(elementResize => {
256
- if (movementRestrictor) {
257
- this.resizeFeedback.add(
258
- movementRestrictionFeedback(elementResize.element, movementRestrictor, elementResize.valid.move),
259
- removeMovementRestrictionFeedback(elementResize.element, movementRestrictor)
260
- );
261
- }
262
- this.resizeFeedback.add(
263
- toggleCssClasses(elementResize.element, !elementResize.valid.size, 'resize-not-allowed'),
264
- deleteCssClasses(elementResize.element, 'resize-not-allowed')
265
- );
266
- });
267
- this.resizeFeedback.add(
268
- toggleCssClasses(resize.handleMove.element, !resize.valid.size, 'resize-not-allowed'),
269
- deleteCssClasses(resize.handleMove.element, 'resize-not-allowed')
270
- );
224
+ this.tool.changeBoundsManager.addResizeFeedback(this.resizeFeedback, resize, target, event);
271
225
  }
272
226
 
273
227
  protected resetBounds(): Action[] {
@@ -27,11 +27,13 @@ import {
27
27
  Vector,
28
28
  Writable,
29
29
  hasBooleanProp,
30
+ hasObjectProp,
31
+ isBoundsAware,
30
32
  isMoveable
31
33
  } from '@eclipse-glsp/sprotty';
32
- import { ChangeBoundsManager } from '..';
33
34
  import { BoundsAwareModelElement, MoveableElement, ResizableModelElement, getElements } from '../../../utils';
34
35
  import { DiagramMovementCalculator, ResizeHandleLocation, SResizeHandle } from '../../change-bounds';
36
+ import { ChangeBoundsManager } from './change-bounds-manager';
35
37
 
36
38
  export interface ElementTrackingOptions {
37
39
  /** Snap position. Default: true. */
@@ -73,6 +75,17 @@ export interface TrackedElementMove extends ResolvedElementMove {
73
75
  valid: boolean;
74
76
  }
75
77
 
78
+ export namespace TrackedElementMove {
79
+ export function is(obj: any): obj is TrackedElementMove {
80
+ return (
81
+ hasObjectProp(obj, 'element') &&
82
+ hasObjectProp(obj, 'fromPosition') &&
83
+ hasObjectProp(obj, 'toPosition') &&
84
+ hasBooleanProp(obj, 'valid')
85
+ );
86
+ }
87
+ }
88
+
76
89
  export type TypedElementMove<T extends MoveableElement> = TrackedElementMove & { element: T };
77
90
 
78
91
  export interface TrackedMove extends Movement {
@@ -134,6 +147,14 @@ export interface TrackedElementResize {
134
147
  };
135
148
  }
136
149
 
150
+ export namespace TrackedElementResize {
151
+ export function is(obj: any): obj is TrackedElementResize {
152
+ return (
153
+ isBoundsAware(obj.element) && hasObjectProp(obj, 'fromBounds') && hasObjectProp(obj, 'toBounds') && hasObjectProp(obj, 'valid')
154
+ );
155
+ }
156
+ }
157
+
137
158
  export interface TrackedResize extends Movement {
138
159
  handleMove: TrackedHandleMove;
139
160
  elementResizes: TrackedElementResize[];
@@ -179,7 +200,7 @@ export class ChangeBoundsTracker {
179
200
  const update = this.calculateDiagramMovement();
180
201
  const move: TrackedMove = { ...update, elementMoves: [], valid: true, options };
181
202
 
182
- if (Vector.isZero(update.vector)) {
203
+ if (Vector.isZero(update.vector) && options.skipStatic) {
183
204
  // no movement detected so elements won't be moved, exit early
184
205
  return move;
185
206
  }
@@ -260,13 +281,13 @@ export class ChangeBoundsTracker {
260
281
  const update = this.calculateDiagramMovement();
261
282
  const handleMove = this.calculateHandleMove(new MoveableResizeHandle(handle), update.vector, options);
262
283
  const resize: TrackedResize = { ...update, valid: { move: true, size: true }, options, handleMove, elementResizes: [] };
263
- if (Vector.isZero(handleMove.moveVector)) {
284
+ if (Vector.isZero(handleMove.moveVector) && options.skipStatic) {
264
285
  // no movement detected so elements won't be moved, exit early
265
286
  return resize;
266
287
  }
267
288
 
268
289
  // calculate resize for each element (typically only one element is resized at a time but customizations are possible)
269
- const elementsToResize = this.getResizeableElements(handle, options);
290
+ const elementsToResize = this.getResizableElements(handle, options);
270
291
  for (const element of elementsToResize) {
271
292
  const elementResize = this.calculateElementResize(element, handleMove, options);
272
293
  if (!this.skipElementResize(elementResize, options)) {
@@ -293,7 +314,7 @@ export class ChangeBoundsTracker {
293
314
  return this.calculateElementMove(handle, diagramMovement, moveOptions);
294
315
  }
295
316
 
296
- protected getResizeableElements(handle: SResizeHandle, options: ResizeOptions): ResizableModelElement[] {
317
+ protected getResizableElements(handle: SResizeHandle, options: ResizeOptions): ResizableModelElement[] {
297
318
  return [handle.parent];
298
319
  }
299
320
 
@@ -25,13 +25,14 @@ import {
25
25
  isConnectable,
26
26
  isCtrlOrCmd
27
27
  } from '@eclipse-glsp/sprotty';
28
- import { inject, injectable } from 'inversify';
28
+ import { inject, injectable, optional } from 'inversify';
29
29
  import { FeedbackEmitter } from '../../../base';
30
30
  import { GLSPActionDispatcher } from '../../../base/action-dispatcher';
31
31
  import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
32
32
  import { CursorCSS, cursorFeedbackAction } from '../../../base/feedback/css-feedback';
33
33
  import { EnableDefaultToolsAction } from '../../../base/tool-manager/tool';
34
34
  import { GEdge } from '../../../model';
35
+ import { Grid } from '../../grid';
35
36
  import { ITypeHintProvider } from '../../hints/type-hint-provider';
36
37
  import { BaseCreationTool } from '../base-tools';
37
38
  import { DrawFeedbackEdgeAction, RemoveFeedbackEdgeAction } from './dangling-edge-feedback';
@@ -45,8 +46,8 @@ export class EdgeCreationTool extends BaseCreationTool<TriggerEdgeCreationAction
45
46
  static ID = 'tool_create_edge';
46
47
 
47
48
  @inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry;
48
-
49
49
  @inject(TYPES.ITypeHintProvider) protected typeHintProvider: ITypeHintProvider;
50
+ @optional() @inject(TYPES.Grid) protected grid: Grid;
50
51
 
51
52
  protected isTriggerAction = TriggerEdgeCreationAction.is;
52
53
 
@@ -59,7 +60,13 @@ export class EdgeCreationTool extends BaseCreationTool<TriggerEdgeCreationAction
59
60
  const toolFeedback = this.createFeedbackEmitter()
60
61
  .add(cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED), cursorFeedbackAction())
61
62
  .submit();
62
- const creationListener = new EdgeCreationToolMouseListener(this.triggerAction, this.actionDispatcher, this.typeHintProvider, this);
63
+ const creationListener = new EdgeCreationToolMouseListener(
64
+ this.triggerAction,
65
+ this.actionDispatcher,
66
+ this.typeHintProvider,
67
+ this,
68
+ this.grid?.x / 2
69
+ );
63
70
  this.toDisposeOnDisable.push(
64
71
  mouseMovingFeedback,
65
72
  this.mouseTool.registerListener(mouseMovingFeedback),
@@ -70,7 +77,6 @@ export class EdgeCreationTool extends BaseCreationTool<TriggerEdgeCreationAction
70
77
  }
71
78
  }
72
79
 
73
- @injectable()
74
80
  export class EdgeCreationToolMouseListener extends DragAwareMouseListener {
75
81
  protected source?: string;
76
82
  protected target?: string;
@@ -85,9 +91,10 @@ export class EdgeCreationToolMouseListener extends DragAwareMouseListener {
85
91
  protected triggerAction: TriggerEdgeCreationAction,
86
92
  protected actionDispatcher: GLSPActionDispatcher,
87
93
  protected typeHintProvider: ITypeHintProvider,
88
- protected tool: EdgeCreationTool
94
+ protected tool: EdgeCreationTool,
95
+ protected dragSensitivity?: number
89
96
  ) {
90
- super();
97
+ super(dragSensitivity);
91
98
  this.proxyEdge = new GEdge();
92
99
  this.proxyEdge.type = triggerAction.elementTypeId;
93
100
  this.cursorFeedback = tool.createFeedbackEmitter();
@@ -41,13 +41,13 @@ import {
41
41
  typeGuard
42
42
  } from '@eclipse-glsp/sprotty';
43
43
  import { inject, injectable } from 'inversify';
44
- import { ChangeBoundsManager, ChangeBoundsTracker, MoveableRoutingHandle } from '..';
45
44
  import { FeedbackEmitter } from '../../../base';
46
45
  import { IFeedbackActionDispatcher } from '../../../base/feedback/feedback-action-dispatcher';
47
46
  import { FeedbackCommand } from '../../../base/feedback/feedback-command';
48
47
  import { forEachElement, getMatchingElements, isRoutable, isRoutingHandle } from '../../../utils/gmodel-util';
49
48
  import { getAbsolutePosition, toAbsoluteBounds } from '../../../utils/viewpoint-util';
50
49
  import { addReconnectHandles, removeReconnectHandles } from '../../reconnect/model';
50
+ import { ChangeBoundsManager, ChangeBoundsTracker, MoveableRoutingHandle } from '../change-bounds';
51
51
  import { FeedbackEdgeEnd, feedbackEdgeEndId, feedbackEdgeId } from '../edge-creation/dangling-edge-feedback';
52
52
  import { FeedbackEdgeEndMovingMouseListener } from '../edge-creation/edge-creation-tool-feedback';
53
53
 
@@ -24,14 +24,12 @@ import {
24
24
  GRoutableElement,
25
25
  GRoutingHandle,
26
26
  ReconnectEdgeOperation,
27
- TYPES,
28
27
  canEditRouting,
29
28
  findParentByFeature,
30
29
  isConnectable,
31
30
  isSelected
32
31
  } from '@eclipse-glsp/sprotty';
33
32
  import { inject, injectable, optional } from 'inversify';
34
- import { ChangeBoundsManager } from '..';
35
33
  import { FeedbackEmitter } from '../../../base';
36
34
  import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
37
35
  import { CursorCSS, cursorFeedbackAction } from '../../../base/feedback/css-feedback';
@@ -39,6 +37,7 @@ import { ISelectionListener, SelectionService } from '../../../base/selection-se
39
37
  import { calcElementAndRoutingPoints, isRoutable, isRoutingHandle } from '../../../utils/gmodel-util';
40
38
  import { GReconnectHandle, isReconnectHandle, isReconnectable, isSourceRoutingHandle, isTargetRoutingHandle } from '../../reconnect/model';
41
39
  import { BaseEditTool } from '../base-tools';
40
+ import { ChangeBoundsManager } from '../change-bounds';
42
41
  import { DrawFeedbackEdgeAction, RemoveFeedbackEdgeAction, feedbackEdgeId } from '../edge-creation/dangling-edge-feedback';
43
42
  import {
44
43
  DrawFeedbackEdgeSourceAction,
@@ -57,7 +56,7 @@ export class EdgeEditTool extends BaseEditTool {
57
56
  @inject(SelectionService) protected selectionService: SelectionService;
58
57
  @inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry;
59
58
  @inject(EdgeRouterRegistry) @optional() readonly edgeRouterRegistry?: EdgeRouterRegistry;
60
- @inject(TYPES.IChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
59
+ @inject(ChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
61
60
 
62
61
  protected feedbackEdgeSourceMovingListener: FeedbackEdgeSourceMovingMouseListener;
63
62
  protected feedbackEdgeTargetMovingListener: FeedbackEdgeTargetMovingMouseListener;
@@ -0,0 +1,76 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2024 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 { GModelElement, Point, findChildrenAtPosition } from '@eclipse-glsp/sprotty';
18
+ import { inject, injectable } from 'inversify';
19
+ import { CSS_GHOST_ELEMENT, CursorCSS, FeedbackEmitter, cursorFeedbackAction } from '../../../base';
20
+ import { ContainerElement, isContainable } from '../../hints';
21
+ import { ChangeBoundsManager } from '../change-bounds';
22
+
23
+ export interface TrackedInsert {
24
+ elementTypeId: string;
25
+ location: Point;
26
+ container?: GModelElement;
27
+ valid: boolean;
28
+ }
29
+
30
+ export interface InsertOptions extends Record<string, unknown> {
31
+ /** Flag to indicate whether the location within a container needs to be valid. Default: false */
32
+ validateLocationInContainer?: boolean;
33
+
34
+ /** Overwrite for location validation if validation result is already known. Default: undefined */
35
+ validLocationOverwrite?: boolean;
36
+
37
+ /** Mouse event to be used for finding the container. Default: undefined */
38
+ evt?: MouseEvent;
39
+ }
40
+
41
+ export const DEFAULT_INSERT_OPTIONS: InsertOptions = {
42
+ validateLocationInContainer: false
43
+ };
44
+
45
+ @injectable()
46
+ export class ContainerManager {
47
+ @inject(ChangeBoundsManager) protected readonly changeBoundsManager: ChangeBoundsManager;
48
+
49
+ insert(proxy: GModelElement, location: Point, elementTypeId: string, opts?: Partial<InsertOptions>): TrackedInsert {
50
+ const options = { ...DEFAULT_INSERT_OPTIONS, ...opts };
51
+ const container = this.findContainer(location, proxy, opts?.evt);
52
+ let valid = !container || container.isContainableElement(elementTypeId);
53
+ if (valid && (!container || options.validateLocationInContainer)) {
54
+ // we need to check whether the location is valid either because we do not have a container or the option is set
55
+ valid = opts?.validLocationOverwrite ?? this.changeBoundsManager.hasValidPosition(proxy, location);
56
+ }
57
+ return { elementTypeId, container, location, valid };
58
+ }
59
+
60
+ findContainer(location: Point, ctx: GModelElement, evt?: MouseEvent): ContainerElement | undefined {
61
+ // reverse order of children to find the innermost, top-rendered containers first
62
+ return findChildrenAtPosition(ctx.root, location)
63
+ .reverse()
64
+ .find(element => isContainable(element) && !element.cssClasses?.includes(CSS_GHOST_ELEMENT)) as ContainerElement | undefined;
65
+ }
66
+
67
+ addInsertFeedback(feedback: FeedbackEmitter, trackedInsert: TrackedInsert, ctx?: GModelElement, event?: MouseEvent): FeedbackEmitter {
68
+ // cursor feedback
69
+ if (!trackedInsert.valid) {
70
+ feedback.add(cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED), cursorFeedbackAction(CursorCSS.DEFAULT));
71
+ } else {
72
+ feedback.add(cursorFeedbackAction(CursorCSS.NODE_CREATION), cursorFeedbackAction());
73
+ }
74
+ return feedback;
75
+ }
76
+ }
@@ -13,5 +13,8 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
+ export * from './container-manager';
17
+ export * from './insert-indicator';
16
18
  export * from './node-creation-module';
17
19
  export * from './node-creation-tool';
20
+ export * from './node-creation-views';
@@ -0,0 +1,41 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2024 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 { Args, Dimension, FeatureSet, GNode, boundsFeature, createFeatureSet, moveFeature } from '@eclipse-glsp/sprotty';
18
+ import { v4 as uuid } from 'uuid';
19
+ import { ArgsAware, argsFeature } from '../../../base/args-feature';
20
+
21
+ export const ARG_LENGTH = 'length';
22
+
23
+ export class InsertIndicator extends GNode implements ArgsAware {
24
+ static override readonly DEFAULT_FEATURES = [boundsFeature, moveFeature, argsFeature];
25
+
26
+ static TYPE = 'node:insert-indicator';
27
+
28
+ override id: string = uuid();
29
+ override type: string = InsertIndicator.TYPE;
30
+ override features?: FeatureSet = createFeatureSet(InsertIndicator.DEFAULT_FEATURES);
31
+ override cssClasses: string[] = ['insert-indicator', 'sprotty-node'];
32
+ override size: Dimension = { width: 1, height: 1 };
33
+ args: Args = {};
34
+
35
+ constructor(length?: number) {
36
+ super();
37
+ if (length) {
38
+ this.args = { [ARG_LENGTH]: length };
39
+ }
40
+ }
41
+ }
@@ -13,15 +13,27 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
- import { FeatureModule, TYPES, TriggerNodeCreationAction, bindAsService, configureActionHandler } from '@eclipse-glsp/sprotty';
16
+ import {
17
+ FeatureModule,
18
+ TYPES,
19
+ TriggerNodeCreationAction,
20
+ bindAsService,
21
+ configureActionHandler,
22
+ configureModelElement
23
+ } from '@eclipse-glsp/sprotty';
17
24
  import { elementTemplateModule } from '../../element-template/element-template-module';
25
+ import { ContainerManager } from './container-manager';
26
+ import { InsertIndicator } from './insert-indicator';
18
27
  import { NodeCreationTool } from './node-creation-tool';
28
+ import { InsertIndicatorView } from './node-creation-views';
19
29
 
20
30
  export const nodeCreationToolModule = new FeatureModule(
21
31
  (bind, unbind, isBound, rebind) => {
22
32
  const context = { bind, unbind, isBound, rebind };
33
+ bind(ContainerManager).toSelf().inSingletonScope();
23
34
  bindAsService(context, TYPES.ITool, NodeCreationTool);
24
35
  configureActionHandler(context, TriggerNodeCreationAction.KIND, NodeCreationTool);
36
+ configureModelElement(context, InsertIndicator.TYPE, InsertIndicator, InsertIndicatorView);
25
37
  },
26
38
  { requires: elementTemplateModule }
27
39
  );