@eclipse-glsp/client 2.2.0-next.333 → 2.2.0-next.334

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 (214) hide show
  1. package/css/change-bounds.css +36 -2
  2. package/css/glsp-sprotty.css +18 -2
  3. package/css/helper-lines.css +3 -3
  4. package/lib/base/default.module.d.ts.map +1 -1
  5. package/lib/base/default.module.js +3 -0
  6. package/lib/base/default.module.js.map +1 -1
  7. package/lib/base/feedback/css-feedback.d.ts +7 -2
  8. package/lib/base/feedback/css-feedback.d.ts.map +1 -1
  9. package/lib/base/feedback/css-feedback.js +10 -2
  10. package/lib/base/feedback/css-feedback.js.map +1 -1
  11. package/lib/base/feedback/feeback-emitter.d.ts +2 -2
  12. package/lib/base/feedback/feeback-emitter.d.ts.map +1 -1
  13. package/lib/base/feedback/feeback-emitter.js +5 -2
  14. package/lib/base/feedback/feeback-emitter.js.map +1 -1
  15. package/lib/base/index.d.ts +1 -0
  16. package/lib/base/index.d.ts.map +1 -1
  17. package/lib/base/index.js +1 -0
  18. package/lib/base/index.js.map +1 -1
  19. package/lib/base/mouse-position-tracker.d.ts +22 -0
  20. package/lib/base/mouse-position-tracker.d.ts.map +1 -0
  21. package/lib/base/mouse-position-tracker.js +40 -0
  22. package/lib/base/mouse-position-tracker.js.map +1 -0
  23. package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts +2 -0
  24. package/lib/features/accessibility/view-key-tools/movement-key-tool.d.ts.map +1 -1
  25. package/lib/features/accessibility/view-key-tools/movement-key-tool.js +15 -7
  26. package/lib/features/accessibility/view-key-tools/movement-key-tool.js.map +1 -1
  27. package/lib/features/bounds/bounds-module.d.ts.map +1 -1
  28. package/lib/features/bounds/bounds-module.js +2 -0
  29. package/lib/features/bounds/bounds-module.js.map +1 -1
  30. package/lib/features/bounds/freeform-layout.d.ts +17 -1
  31. package/lib/features/bounds/freeform-layout.d.ts.map +1 -1
  32. package/lib/features/bounds/freeform-layout.js +14 -5
  33. package/lib/features/bounds/freeform-layout.js.map +1 -1
  34. package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts +5 -4
  35. package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts.map +1 -1
  36. package/lib/features/bounds/glsp-hidden-bounds-updater.js +51 -39
  37. package/lib/features/bounds/glsp-hidden-bounds-updater.js.map +1 -1
  38. package/lib/features/bounds/hbox-layout.d.ts +18 -2
  39. package/lib/features/bounds/hbox-layout.d.ts.map +1 -1
  40. package/lib/features/bounds/hbox-layout.js +14 -5
  41. package/lib/features/bounds/hbox-layout.js.map +1 -1
  42. package/lib/features/bounds/index.d.ts +1 -0
  43. package/lib/features/bounds/index.d.ts.map +1 -1
  44. package/lib/features/bounds/index.js +1 -0
  45. package/lib/features/bounds/index.js.map +1 -1
  46. package/lib/features/bounds/layout-data.d.ts +27 -0
  47. package/lib/features/bounds/layout-data.d.ts.map +1 -0
  48. package/lib/features/bounds/layout-data.js +48 -0
  49. package/lib/features/bounds/layout-data.js.map +1 -0
  50. package/lib/features/bounds/local-bounds.d.ts +3 -1
  51. package/lib/features/bounds/local-bounds.d.ts.map +1 -1
  52. package/lib/features/bounds/local-bounds.js +14 -0
  53. package/lib/features/bounds/local-bounds.js.map +1 -1
  54. package/lib/features/bounds/vbox-layout.d.ts +18 -2
  55. package/lib/features/bounds/vbox-layout.d.ts.map +1 -1
  56. package/lib/features/bounds/vbox-layout.js +14 -5
  57. package/lib/features/bounds/vbox-layout.js.map +1 -1
  58. package/lib/features/change-bounds/index.d.ts +1 -0
  59. package/lib/features/change-bounds/index.d.ts.map +1 -1
  60. package/lib/features/change-bounds/index.js +1 -0
  61. package/lib/features/change-bounds/index.js.map +1 -1
  62. package/lib/features/change-bounds/model.d.ts +19 -3
  63. package/lib/features/change-bounds/model.d.ts.map +1 -1
  64. package/lib/features/change-bounds/model.js +92 -4
  65. package/lib/features/change-bounds/model.js.map +1 -1
  66. package/lib/features/change-bounds/movement-restrictor.d.ts +1 -0
  67. package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
  68. package/lib/features/change-bounds/movement-restrictor.js +7 -1
  69. package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
  70. package/lib/features/change-bounds/point-position-updater.d.ts +3 -0
  71. package/lib/features/change-bounds/point-position-updater.d.ts.map +1 -1
  72. package/lib/features/change-bounds/point-position-updater.js +7 -2
  73. package/lib/features/change-bounds/point-position-updater.js.map +1 -1
  74. package/lib/features/change-bounds/position-snapper.d.ts +4 -0
  75. package/lib/features/change-bounds/position-snapper.d.ts.map +1 -1
  76. package/lib/features/change-bounds/position-snapper.js +4 -0
  77. package/lib/features/change-bounds/position-snapper.js.map +1 -1
  78. package/lib/features/change-bounds/snap.d.ts +6 -0
  79. package/lib/features/change-bounds/snap.d.ts.map +1 -1
  80. package/lib/features/change-bounds/snap.js +6 -0
  81. package/lib/features/change-bounds/snap.js.map +1 -1
  82. package/lib/features/change-bounds/tracker.d.ts +32 -0
  83. package/lib/features/change-bounds/tracker.d.ts.map +1 -0
  84. package/lib/features/change-bounds/tracker.js +60 -0
  85. package/lib/features/change-bounds/tracker.js.map +1 -0
  86. package/lib/features/debug/debug-bounds-decorator.d.ts +4 -1
  87. package/lib/features/debug/debug-bounds-decorator.d.ts.map +1 -1
  88. package/lib/features/debug/debug-bounds-decorator.js +14 -7
  89. package/lib/features/debug/debug-bounds-decorator.js.map +1 -1
  90. package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts +9 -22
  91. package/lib/features/element-template/mouse-tracking-element-position-listener.d.ts.map +1 -1
  92. package/lib/features/element-template/mouse-tracking-element-position-listener.js +30 -46
  93. package/lib/features/element-template/mouse-tracking-element-position-listener.js.map +1 -1
  94. package/lib/features/helper-lines/helper-line-feedback.d.ts +2 -2
  95. package/lib/features/helper-lines/helper-line-feedback.d.ts.map +1 -1
  96. package/lib/features/helper-lines/helper-line-feedback.js +1 -1
  97. package/lib/features/helper-lines/helper-line-feedback.js.map +1 -1
  98. package/lib/features/helper-lines/helper-line-manager-default.d.ts +2 -1
  99. package/lib/features/helper-lines/helper-line-manager-default.d.ts.map +1 -1
  100. package/lib/features/helper-lines/helper-line-manager-default.js +23 -0
  101. package/lib/features/helper-lines/helper-line-manager-default.js.map +1 -1
  102. package/lib/features/helper-lines/helper-line-manager.d.ts +10 -2
  103. package/lib/features/helper-lines/helper-line-manager.d.ts.map +1 -1
  104. package/lib/features/routing/edge-router.d.ts +4 -0
  105. package/lib/features/routing/edge-router.d.ts.map +1 -1
  106. package/lib/features/routing/edge-router.js +37 -0
  107. package/lib/features/routing/edge-router.js.map +1 -1
  108. package/lib/features/select/select-mouse-listener.d.ts +3 -0
  109. package/lib/features/select/select-mouse-listener.d.ts.map +1 -1
  110. package/lib/features/select/select-mouse-listener.js +30 -2
  111. package/lib/features/select/select-mouse-listener.js.map +1 -1
  112. package/lib/features/tools/base-tools.d.ts +24 -15
  113. package/lib/features/tools/base-tools.d.ts.map +1 -1
  114. package/lib/features/tools/base-tools.js +0 -18
  115. package/lib/features/tools/base-tools.js.map +1 -1
  116. package/lib/features/tools/change-bounds/change-bounds-manager.d.ts +42 -0
  117. package/lib/features/tools/change-bounds/change-bounds-manager.d.ts.map +1 -0
  118. package/lib/features/tools/change-bounds/change-bounds-manager.js +136 -0
  119. package/lib/features/tools/change-bounds/change-bounds-manager.js.map +1 -0
  120. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts +6 -0
  121. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.d.ts.map +1 -1
  122. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js +14 -8
  123. package/lib/features/tools/change-bounds/change-bounds-tool-feedback.js.map +1 -1
  124. package/lib/features/tools/change-bounds/change-bounds-tool-module.d.ts.map +1 -1
  125. package/lib/features/tools/change-bounds/change-bounds-tool-module.js +2 -0
  126. package/lib/features/tools/change-bounds/change-bounds-tool-module.js.map +1 -1
  127. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts +6 -15
  128. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts.map +1 -1
  129. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js +24 -72
  130. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js.map +1 -1
  131. package/lib/features/tools/change-bounds/change-bounds-tool.d.ts +14 -25
  132. package/lib/features/tools/change-bounds/change-bounds-tool.d.ts.map +1 -1
  133. package/lib/features/tools/change-bounds/change-bounds-tool.js +63 -109
  134. package/lib/features/tools/change-bounds/change-bounds-tool.js.map +1 -1
  135. package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts +136 -0
  136. package/lib/features/tools/change-bounds/change-bounds-tracker.d.ts.map +1 -0
  137. package/lib/features/tools/change-bounds/change-bounds-tracker.js +301 -0
  138. package/lib/features/tools/change-bounds/change-bounds-tracker.js.map +1 -0
  139. package/lib/features/tools/change-bounds/index.d.ts +2 -0
  140. package/lib/features/tools/change-bounds/index.d.ts.map +1 -1
  141. package/lib/features/tools/change-bounds/index.js +2 -0
  142. package/lib/features/tools/change-bounds/index.js.map +1 -1
  143. package/lib/features/tools/change-bounds/view.d.ts.map +1 -1
  144. package/lib/features/tools/change-bounds/view.js +1 -16
  145. package/lib/features/tools/change-bounds/view.js.map +1 -1
  146. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts +7 -9
  147. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.d.ts.map +1 -1
  148. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js +27 -47
  149. package/lib/features/tools/edge-edit/edge-edit-tool-feedback.js.map +1 -1
  150. package/lib/features/tools/edge-edit/edge-edit-tool.d.ts +2 -2
  151. package/lib/features/tools/edge-edit/edge-edit-tool.d.ts.map +1 -1
  152. package/lib/features/tools/edge-edit/edge-edit-tool.js +5 -5
  153. package/lib/features/tools/edge-edit/edge-edit-tool.js.map +1 -1
  154. package/lib/features/tools/marquee-selection/marquee-mouse-tool.d.ts +1 -0
  155. package/lib/features/tools/marquee-selection/marquee-mouse-tool.d.ts.map +1 -1
  156. package/lib/features/tools/marquee-selection/marquee-mouse-tool.js +3 -0
  157. package/lib/features/tools/marquee-selection/marquee-mouse-tool.js.map +1 -1
  158. package/lib/features/tools/node-creation/node-creation-tool.d.ts +2 -4
  159. package/lib/features/tools/node-creation/node-creation-tool.d.ts.map +1 -1
  160. package/lib/features/tools/node-creation/node-creation-tool.js +8 -11
  161. package/lib/features/tools/node-creation/node-creation-tool.js.map +1 -1
  162. package/lib/utils/gmodel-util.d.ts +20 -1
  163. package/lib/utils/gmodel-util.d.ts.map +1 -1
  164. package/lib/utils/gmodel-util.js +38 -16
  165. package/lib/utils/gmodel-util.js.map +1 -1
  166. package/lib/utils/layout-utils.d.ts +1 -0
  167. package/lib/utils/layout-utils.d.ts.map +1 -1
  168. package/lib/utils/layout-utils.js +5 -1
  169. package/lib/utils/layout-utils.js.map +1 -1
  170. package/package.json +3 -3
  171. package/src/base/default.module.ts +4 -1
  172. package/src/base/feedback/css-feedback.ts +10 -2
  173. package/src/base/feedback/feeback-emitter.ts +6 -3
  174. package/src/base/index.ts +1 -0
  175. package/src/base/mouse-position-tracker.ts +25 -0
  176. package/src/features/accessibility/view-key-tools/movement-key-tool.ts +12 -7
  177. package/src/features/bounds/bounds-module.ts +2 -0
  178. package/src/features/bounds/freeform-layout.ts +16 -6
  179. package/src/features/bounds/glsp-hidden-bounds-updater.ts +63 -46
  180. package/src/features/bounds/hbox-layout.ts +18 -9
  181. package/src/features/bounds/index.ts +1 -0
  182. package/src/features/bounds/layout-data.ts +48 -0
  183. package/src/features/bounds/local-bounds.ts +20 -4
  184. package/src/features/bounds/vbox-layout.ts +18 -10
  185. package/src/features/change-bounds/index.ts +1 -0
  186. package/src/features/change-bounds/model.ts +104 -4
  187. package/src/features/change-bounds/movement-restrictor.ts +10 -0
  188. package/src/features/change-bounds/point-position-updater.spec.ts +2 -0
  189. package/src/features/change-bounds/point-position-updater.ts +6 -0
  190. package/src/features/change-bounds/position-snapper.ts +4 -0
  191. package/src/features/change-bounds/snap.ts +6 -0
  192. package/src/features/change-bounds/tracker.ts +63 -0
  193. package/src/features/debug/debug-bounds-decorator.tsx +17 -7
  194. package/src/features/element-template/mouse-tracking-element-position-listener.ts +49 -71
  195. package/src/features/helper-lines/helper-line-feedback.ts +2 -1
  196. package/src/features/helper-lines/helper-line-manager-default.ts +37 -2
  197. package/src/features/helper-lines/helper-line-manager.ts +11 -2
  198. package/src/features/routing/edge-router.ts +42 -0
  199. package/src/features/select/select-mouse-listener.ts +15 -1
  200. package/src/features/tools/base-tools.ts +31 -19
  201. package/src/features/tools/change-bounds/change-bounds-manager.ts +145 -0
  202. package/src/features/tools/change-bounds/change-bounds-tool-feedback.ts +17 -6
  203. package/src/features/tools/change-bounds/change-bounds-tool-module.ts +2 -0
  204. package/src/features/tools/change-bounds/change-bounds-tool-move-feedback.ts +31 -81
  205. package/src/features/tools/change-bounds/change-bounds-tool.ts +89 -148
  206. package/src/features/tools/change-bounds/change-bounds-tracker.ts +455 -0
  207. package/src/features/tools/change-bounds/index.ts +2 -0
  208. package/src/features/tools/change-bounds/view.tsx +2 -14
  209. package/src/features/tools/edge-edit/edge-edit-tool-feedback.ts +34 -52
  210. package/src/features/tools/edge-edit/edge-edit-tool.ts +4 -3
  211. package/src/features/tools/marquee-selection/marquee-mouse-tool.ts +4 -0
  212. package/src/features/tools/node-creation/node-creation-tool.ts +7 -7
  213. package/src/utils/gmodel-util.ts +41 -5
  214. package/src/utils/layout-utils.ts +4 -0
@@ -37,11 +37,18 @@ import {
37
37
  TYPES,
38
38
  findParentByFeature
39
39
  } from '@eclipse-glsp/sprotty';
40
+ import { CSS_RESIZE_MODE, ChangeBoundsManager, ChangeBoundsTracker, TrackedElementResize, TrackedResize } from '..';
40
41
  import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
41
- import { CursorCSS, applyCssClasses, cursorFeedbackAction, deleteCssClasses } from '../../../base/feedback/css-feedback';
42
+ import {
43
+ CursorCSS,
44
+ ModifyCSSFeedbackAction,
45
+ applyCssClasses,
46
+ cursorFeedbackAction,
47
+ deleteCssClasses,
48
+ toggleCssClasses
49
+ } from '../../../base/feedback/css-feedback';
42
50
  import { FeedbackEmitter } from '../../../base/feedback/feeback-emitter';
43
51
  import { ISelectionListener, SelectionService } from '../../../base/selection-service';
44
- import { isValidMove, isValidSize } from '../../../utils';
45
52
  import {
46
53
  BoundsAwareModelElement,
47
54
  ResizableModelElement,
@@ -51,16 +58,13 @@ import {
51
58
  isNonRoutableSelectedMovableBoundsAware,
52
59
  toElementAndBounds
53
60
  } from '../../../utils/gmodel-util';
54
- import { SetBoundsFeedbackAction } from '../../bounds';
55
- import { PointPositionUpdater } from '../../change-bounds';
56
- import { ResizeHandleLocation, SResizeHandle, isResizable } from '../../change-bounds/model';
61
+ import { LocalRequestBoundsAction, SetBoundsFeedbackAction } from '../../bounds';
62
+ import { SResizeHandle, isResizable } from '../../change-bounds/model';
57
63
  import {
58
64
  IMovementRestrictor,
59
- createMovementRestrictionFeedback,
65
+ movementRestrictionFeedback,
60
66
  removeMovementRestrictionFeedback
61
67
  } from '../../change-bounds/movement-restrictor';
62
- import { PositionSnapper } from '../../change-bounds/position-snapper';
63
- import { getDirectionFrom } from '../../helper-lines';
64
68
  import { BaseEditTool } from '../base-tools';
65
69
  import {
66
70
  HideChangeBoundsToolResizeFeedbackAction,
@@ -89,7 +93,7 @@ export class ChangeBoundsTool extends BaseEditTool {
89
93
  @inject(SelectionService) protected selectionService: SelectionService;
90
94
  @inject(EdgeRouterRegistry) @optional() readonly edgeRouterRegistry?: EdgeRouterRegistry;
91
95
  @inject(TYPES.IMovementRestrictor) @optional() readonly movementRestrictor?: IMovementRestrictor;
92
- @inject(PositionSnapper) readonly positionSnapper: PositionSnapper;
96
+ @inject(TYPES.IChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
93
97
 
94
98
  get id(): string {
95
99
  return ChangeBoundsTool.ID;
@@ -115,6 +119,10 @@ export class ChangeBoundsTool extends BaseEditTool {
115
119
  );
116
120
  }
117
121
 
122
+ createChangeBoundsTracker(): ChangeBoundsTracker {
123
+ return this.changeBoundsManager.createTracker();
124
+ }
125
+
118
126
  protected createMoveMouseListener(): MouseListener {
119
127
  return new FeedbackMoveMouseListener(this);
120
128
  }
@@ -124,22 +132,12 @@ export class ChangeBoundsTool extends BaseEditTool {
124
132
  }
125
133
  }
126
134
 
127
- export interface ValidatedElementAndBounds extends ElementAndBounds {
128
- valid: boolean;
129
- }
130
-
131
- export namespace ValidatedElementAndBounds {
132
- export function isValid(move: ElementAndBounds): boolean {
133
- return (move as ValidatedElementAndBounds).valid ?? true;
134
- }
135
- }
136
-
137
- export class ChangeBoundsListener extends DragAwareMouseListener implements ISelectionListener, Disposable {
135
+ export class ChangeBoundsListener extends DragAwareMouseListener implements ISelectionListener {
138
136
  static readonly CSS_CLASS_ACTIVE = 'active';
139
137
 
140
138
  // members for calculating the correct position change
141
139
  protected initialBounds: ElementAndBounds | undefined;
142
- protected positionUpdater: PointPositionUpdater;
140
+ protected tracker: ChangeBoundsTracker;
143
141
 
144
142
  // members for resize mode
145
143
  protected activeResizeElement?: ResizableModelElement;
@@ -149,7 +147,7 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
149
147
 
150
148
  constructor(protected tool: ChangeBoundsTool) {
151
149
  super();
152
- this.positionUpdater = new PointPositionUpdater(tool.positionSnapper);
150
+ this.tracker = tool.createChangeBoundsTracker();
153
151
  this.handleFeedback = tool.createFeedbackEmitter();
154
152
  this.resizeFeedback = tool.createFeedbackEmitter();
155
153
  }
@@ -171,22 +169,28 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
171
169
  this.activeResizeElement = this.activeResizeHandle?.parent ?? this.findResizeElement(target);
172
170
  if (this.activeResizeElement) {
173
171
  if (event) {
174
- this.positionUpdater.updateLastDragPosition(event);
172
+ this.tracker.startTracking();
175
173
  }
176
174
  this.initialBounds = {
177
175
  newSize: this.activeResizeElement.bounds,
178
176
  newPosition: this.activeResizeElement.bounds,
179
177
  elementId: this.activeResizeElement.id
180
178
  };
179
+ // we trigger the local bounds calculation once to get the correct layout information for reszing
180
+ // for any sub-sequent calls the layout information will be updated automatically
181
+ this.tool
182
+ .createFeedbackEmitter()
183
+ .add(LocalRequestBoundsAction.create(target.root, [this.activeResizeElement.id]))
184
+ .submit()
185
+ .dispose();
181
186
  this.handleFeedback.add(
182
- ShowChangeBoundsToolResizeFeedbackAction.create(this.activeResizeElement.id),
187
+ ShowChangeBoundsToolResizeFeedbackAction.create({ elementId: this.activeResizeElement.id }),
183
188
  HideChangeBoundsToolResizeFeedbackAction.create()
184
189
  );
185
190
  this.handleFeedback.submit();
186
191
  return true;
187
192
  } else {
188
- this.positionUpdater.resetPosition();
189
- this.handleFeedback.dispose();
193
+ this.dispose();
190
194
  return false;
191
195
  }
192
196
  }
@@ -200,74 +204,81 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
200
204
  protected override draggingMouseMove(target: GModelElement, event: MouseEvent): Action[] {
201
205
  // rely on the FeedbackMoveMouseListener to update the element bounds of selected elements
202
206
  // consider resize handles ourselves
203
- if (this.activeResizeHandle && !this.positionUpdater.isLastDragPositionUndefined()) {
204
- if (!this.initialBounds) {
205
- const element = this.activeResizeHandle.parent;
206
- this.initialBounds = { elementId: element.id, newSize: element.bounds, newPosition: element.bounds };
207
- }
208
- const positionUpdate = this.positionUpdater.updatePosition(target, event, getDirectionFrom(this.activeResizeHandle.location));
209
- if (positionUpdate) {
210
- const resizeActions = this.handleResizeOnClient(positionUpdate).filter(action => action);
211
- if (resizeActions.length > 0) {
212
- this.resizeFeedback.add(SetBoundsFeedbackAction.create(resizeActions), () => this.resetBoundsAction());
213
- this.addResizeFeedback(resizeActions, this.activeResizeHandle, target, event);
214
- this.resizeFeedback.submit();
215
- }
207
+ if (this.activeResizeHandle && this.tracker.isTracking()) {
208
+ const resize = this.tracker.resizeElements(this.activeResizeHandle, { snap: event, symmetric: event, restrict: event });
209
+ this.addResizeFeedback(resize, target, event);
210
+ const resizeAction = this.resizeBoundsAction(resize);
211
+ if (resizeAction.bounds.length > 0) {
212
+ this.resizeFeedback.add(resizeAction, () => this.resetBounds());
213
+ this.tracker.updateTrackingPosition(resize.handleMove.moveVector);
214
+ } else {
215
+ this.resizeFeedback.add(undefined, () => this.resetBounds());
216
216
  }
217
+ this.resizeFeedback.submit();
217
218
  }
218
219
  return super.draggingMouseMove(target, event);
219
220
  }
220
221
 
221
- protected filterResizeOnClient(resize: ValidatedElementAndBounds, positionUpdate: Point): boolean {
222
- return true;
222
+ protected resizeBoundsAction(resize: TrackedResize): SetBoundsFeedbackAction {
223
+ // we do not want to resize elements beyond their valid size, not even for feedback, as the next layout cycle usually corrects this
224
+ const elementResizes = resize.elementResizes.filter(elementResize => elementResize.valid.size);
225
+ return SetBoundsFeedbackAction.create(elementResizes.map(elementResize => this.toElementAndBounds(elementResize)));
223
226
  }
224
227
 
225
- protected addResizeFeedback(
226
- resizeActions: ValidatedElementAndBounds[],
227
- handle: SResizeHandle,
228
- target: GModelElement,
229
- event: MouseEvent
230
- ): void {
228
+ protected toElementAndBounds(elementResize: TrackedElementResize): ElementAndBounds {
229
+ return {
230
+ elementId: elementResize.element.id,
231
+ newSize: elementResize.toBounds,
232
+ newPosition: elementResize.toBounds
233
+ };
234
+ }
235
+
236
+ protected addResizeFeedback(resize: TrackedResize, target: GModelElement, event: MouseEvent): void {
237
+ const handle = resize.handleMove.element;
231
238
  // handle feedback
232
239
  this.resizeFeedback.add(
233
240
  applyCssClasses(handle, ChangeBoundsListener.CSS_CLASS_ACTIVE),
234
241
  deleteCssClasses(handle, ChangeBoundsListener.CSS_CLASS_ACTIVE)
235
242
  );
236
243
 
244
+ // graph feedback
245
+ this.resizeFeedback.add(
246
+ ModifyCSSFeedbackAction.create({ add: [CSS_RESIZE_MODE] }),
247
+ ModifyCSSFeedbackAction.create({ remove: [CSS_RESIZE_MODE] })
248
+ );
249
+
237
250
  // cursor feedback
238
- const cursorClass = handle.isNeResize()
239
- ? CursorCSS.RESIZE_NE
240
- : handle.isNwResize()
241
- ? CursorCSS.RESIZE_NW
242
- : handle.isSeResize()
243
- ? CursorCSS.RESIZE_SE
244
- : CursorCSS.RESIZE_SW;
251
+ const cursorClass = SResizeHandle.getCursorCss(resize.handleMove.element);
245
252
  this.resizeFeedback.add(cursorFeedbackAction(cursorClass), cursorFeedbackAction(CursorCSS.DEFAULT));
246
253
 
247
- // restriction feedback
248
- resizeActions.forEach(elementResize => {
249
- const element = handle.root.index.getById(elementResize.elementId);
250
- if (element && this.tool.movementRestrictor) {
251
- if (!elementResize.valid) {
252
- this.resizeFeedback.add(createMovementRestrictionFeedback(element, this.tool.movementRestrictor), () =>
253
- removeMovementRestrictionFeedback(element, this.tool.movementRestrictor!)
254
- );
255
- } else {
256
- this.resizeFeedback.add(removeMovementRestrictionFeedback(element, this.tool.movementRestrictor!));
257
- }
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
+ );
258
261
  }
262
+ this.resizeFeedback.add(
263
+ toggleCssClasses(elementResize.element, !elementResize.valid.size, 'resize-not-allowed'),
264
+ deleteCssClasses(elementResize.element, 'resize-not-allowed')
265
+ );
259
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
+ );
260
271
  }
261
272
 
262
- protected resetBoundsAction(): Action[] {
273
+ protected resetBounds(): Action[] {
263
274
  // reset the bounds to the initial bounds and ensure that we do not show helper line feedback anymore (MoveFinishedEventAction)
264
275
  return this.initialBounds
265
276
  ? [SetBoundsFeedbackAction.create([this.initialBounds]), MoveFinishedEventAction.create()]
266
277
  : [MoveFinishedEventAction.create()];
267
278
  }
268
279
 
269
- override draggingMouseUp(target: GModelElement, _event: MouseEvent): Action[] {
270
- if (this.positionUpdater.isLastDragPositionUndefined()) {
280
+ override draggingMouseUp(target: GModelElement, event: MouseEvent): Action[] {
281
+ if (!this.tracker.isTracking()) {
271
282
  return [];
272
283
  }
273
284
  const actions: Action[] = [];
@@ -296,17 +307,13 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
296
307
  const selectedElements = getMatchingElements(target.index, isNonRoutableSelectedMovableBoundsAware);
297
308
  const selectionSet: Set<BoundsAwareModelElement> = new Set(selectedElements);
298
309
  const newBounds: ElementAndBounds[] = selectedElements
299
- .filter(element => this.isValidElement(element, selectionSet))
310
+ .filter(element => this.isValidMove(element, selectionSet))
300
311
  .map(toElementAndBounds);
301
312
  return newBounds.length > 0 ? [ChangeBoundsOperation.create(newBounds)] : [];
302
313
  }
303
314
 
304
- protected isValidElement(element: BoundsAwareModelElement, selectedElements: Set<BoundsAwareModelElement> = new Set()): boolean {
305
- return (
306
- this.isValidMove(element, element.bounds) &&
307
- this.isValidSize(element, element.bounds) &&
308
- !this.isChildOfSelected(selectedElements, element)
309
- );
315
+ protected isValidMove(element: BoundsAwareModelElement, selectedElements: Set<BoundsAwareModelElement> = new Set()): boolean {
316
+ return this.tool.changeBoundsManager.hasValidPosition(element) && !this.isChildOfSelected(selectedElements, element);
310
317
  }
311
318
 
312
319
  protected isChildOfSelected(selectedElements: Set<GModelElement>, element: GModelElement): boolean {
@@ -342,7 +349,7 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
342
349
  }
343
350
 
344
351
  protected handleResizeOnServer(activeResizeHandle: SResizeHandle): Action[] {
345
- if (this.isValidElement(activeResizeHandle.parent) && this.initialBounds) {
352
+ if (this.initialBounds && this.isValidResize(activeResizeHandle.parent)) {
346
353
  const elementAndBounds = toElementAndBounds(activeResizeHandle.parent);
347
354
  if (!this.initialBounds.newPosition || !elementAndBounds.newPosition) {
348
355
  return [];
@@ -361,6 +368,10 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
361
368
  return [];
362
369
  }
363
370
 
371
+ protected isValidResize(element: BoundsAwareModelElement): boolean {
372
+ return this.tool.changeBoundsManager.isValid(element);
373
+ }
374
+
364
375
  selectionChanged(root: GModelRoot, selectedElements: string[]): void {
365
376
  if (this.activeResizeElement && selectedElements.includes(this.activeResizeElement.id)) {
366
377
  // our active element is still selected, nothing to do
@@ -374,88 +385,18 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements ISel
374
385
  return;
375
386
  }
376
387
  }
377
- this.updateResizeElement(root);
378
- this.disposeAllButHandles();
388
+ this.dispose();
379
389
  }
380
390
 
381
391
  protected isActiveResizeElement(element?: GModelElement): element is GParentElement & BoundsAware {
382
392
  return element !== undefined && this.activeResizeElement !== undefined && element.id === this.activeResizeElement.id;
383
393
  }
384
394
 
385
- protected handleResizeOnClient(positionUpdate: Point): ValidatedElementAndBounds[] {
386
- if (!this.activeResizeHandle) {
387
- return [];
388
- }
389
-
390
- if (this.isActiveResizeElement(this.activeResizeHandle.parent)) {
391
- switch (this.activeResizeHandle.location) {
392
- case ResizeHandleLocation.TopLeft:
393
- return this.handleTopLeftResize(this.activeResizeHandle.parent, positionUpdate);
394
- case ResizeHandleLocation.TopRight:
395
- return this.handleTopRightResize(this.activeResizeHandle.parent, positionUpdate);
396
- case ResizeHandleLocation.BottomLeft:
397
- return this.handleBottomLeftResize(this.activeResizeHandle.parent, positionUpdate);
398
- case ResizeHandleLocation.BottomRight:
399
- return this.handleBottomRightResize(this.activeResizeHandle.parent, positionUpdate);
400
- }
401
- }
402
- return [];
403
- }
404
-
405
- protected handleTopLeftResize(resizeElement: ResizableModelElement, positionUpdate: Point): ValidatedElementAndBounds[] {
406
- return this.createSetBoundsAction(
407
- resizeElement,
408
- { x: resizeElement.bounds.x + positionUpdate.x, y: resizeElement.bounds.y + positionUpdate.y },
409
- { width: resizeElement.bounds.width - positionUpdate.x, height: resizeElement.bounds.height - positionUpdate.y }
410
- );
411
- }
412
-
413
- protected handleTopRightResize(resizeElement: ResizableModelElement, positionUpdate: Point): ValidatedElementAndBounds[] {
414
- return this.createSetBoundsAction(
415
- resizeElement,
416
- { x: resizeElement.bounds.x, y: resizeElement.bounds.y + positionUpdate.y },
417
- { width: resizeElement.bounds.width + positionUpdate.x, height: resizeElement.bounds.height - positionUpdate.y }
418
- );
419
- }
420
-
421
- protected handleBottomLeftResize(resizeElement: ResizableModelElement, positionUpdate: Point): ValidatedElementAndBounds[] {
422
- return this.createSetBoundsAction(
423
- resizeElement,
424
- { x: resizeElement.bounds.x + positionUpdate.x, y: resizeElement.bounds.y },
425
- { width: resizeElement.bounds.width - positionUpdate.x, height: resizeElement.bounds.height + positionUpdate.y }
426
- );
427
- }
428
-
429
- protected handleBottomRightResize(resizeElement: ResizableModelElement, positionUpdate: Point): ValidatedElementAndBounds[] {
430
- return this.createSetBoundsAction(
431
- resizeElement,
432
- { x: resizeElement.bounds.x, y: resizeElement.bounds.y },
433
- { width: resizeElement.bounds.width + positionUpdate.x, height: resizeElement.bounds.height + positionUpdate.y }
434
- );
435
- }
436
-
437
- protected createSetBoundsAction(element: BoundsAwareModelElement, newPosition: Point, newSize: Dimension): ValidatedElementAndBounds[] {
438
- if (!isValidSize(element, newSize)) {
439
- // we are not allowing any invalid sizes (breaking min size), not even during client feedback
440
- return [];
441
- }
442
- const valid = this.isValidMove(element, newPosition);
443
- return [{ elementId: element.id, newPosition, newSize, valid }];
444
- }
445
-
446
- protected isValidSize(element: BoundsAwareModelElement, size: Dimension): boolean {
447
- return isValidSize(element, size);
448
- }
449
-
450
- protected isValidMove(element: BoundsAwareModelElement, newPosition: Point): boolean {
451
- return isValidMove(element, newPosition, this.tool.movementRestrictor);
452
- }
453
-
454
395
  protected disposeAllButHandles(): void {
455
396
  // We do not dispose the handle feedback as we want to keep showing the handles on selected elements
456
397
  // this.handleFeedback.dispose();
457
398
  this.resizeFeedback.dispose();
458
- this.positionUpdater.resetPosition();
399
+ this.tracker.dispose();
459
400
  this.activeResizeElement = undefined;
460
401
  this.activeResizeHandle = undefined;
461
402
  this.initialBounds = undefined;