@eclipse-glsp/client 0.10.0-next.e5fcffe.169 → 1.1.0-next.fe0b297.182
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/css/decoration.css +5 -1
- package/css/glsp-sprotty.css +39 -0
- package/css/tool-palette.css +2 -2
- package/lib/base/container-modules.d.ts.map +1 -1
- package/lib/base/container-modules.js +10 -9
- package/lib/base/container-modules.js.map +1 -1
- package/lib/base/editor-context-service.d.ts +2 -3
- package/lib/base/editor-context-service.d.ts.map +1 -1
- package/lib/base/editor-context-service.js +11 -12
- package/lib/base/editor-context-service.js.map +1 -1
- package/lib/base/model/update-model-command.d.ts +14 -7
- package/lib/base/model/update-model-command.d.ts.map +1 -1
- package/lib/base/model/update-model-command.js +31 -41
- package/lib/base/model/update-model-command.js.map +1 -1
- package/lib/base/source-uri-aware.d.ts +2 -17
- package/lib/base/source-uri-aware.d.ts.map +1 -1
- package/lib/base/source-uri-aware.js +4 -6
- package/lib/base/source-uri-aware.js.map +1 -1
- package/lib/features/change-bounds/movement-restrictor.d.ts +36 -6
- package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
- package/lib/features/change-bounds/movement-restrictor.js +54 -39
- package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
- package/lib/features/change-bounds/snap.d.ts +20 -5
- package/lib/features/change-bounds/snap.d.ts.map +1 -1
- package/lib/features/change-bounds/snap.js +19 -8
- package/lib/features/change-bounds/snap.js.map +1 -1
- package/lib/features/context-menu/selection-service-aware-context-menu-mouse-listener.d.ts +5 -7
- package/lib/features/context-menu/selection-service-aware-context-menu-mouse-listener.d.ts.map +1 -1
- package/lib/features/context-menu/selection-service-aware-context-menu-mouse-listener.js +7 -14
- package/lib/features/context-menu/selection-service-aware-context-menu-mouse-listener.js.map +1 -1
- package/lib/features/hover/hover.d.ts +1 -2
- package/lib/features/hover/hover.d.ts.map +1 -1
- package/lib/features/hover/hover.js +2 -15
- package/lib/features/hover/hover.js.map +1 -1
- package/lib/features/layout/di.config.d.ts +2 -2
- package/lib/features/layout/di.config.d.ts.map +1 -1
- package/lib/features/layout/di.config.js +6 -5
- package/lib/features/layout/di.config.js.map +1 -1
- package/lib/features/layout/{layout-commands.d.ts → layout-elements-action.d.ts} +75 -57
- package/lib/features/layout/layout-elements-action.d.ts.map +1 -0
- package/lib/features/layout/{layout-commands.js → layout-elements-action.js} +153 -197
- package/lib/features/layout/layout-elements-action.js.map +1 -0
- package/lib/features/layout/layout-elements-action.spec.d.ts +3 -0
- package/lib/features/layout/layout-elements-action.spec.d.ts.map +1 -0
- package/lib/features/layout/{layout-commands.spec.js → layout-elements-action.spec.js} +63 -56
- package/lib/features/layout/layout-elements-action.spec.js.map +1 -0
- package/lib/features/mouse-tool/mouse-tool.d.ts +0 -1
- package/lib/features/mouse-tool/mouse-tool.d.ts.map +1 -1
- package/lib/features/mouse-tool/mouse-tool.js +9 -5
- package/lib/features/mouse-tool/mouse-tool.js.map +1 -1
- package/lib/features/select/select-mouse-listener.d.ts +3 -1
- package/lib/features/select/select-mouse-listener.d.ts.map +1 -1
- package/lib/features/select/select-mouse-listener.js +62 -0
- package/lib/features/select/select-mouse-listener.js.map +1 -1
- package/lib/features/select/selection-service.d.ts +12 -3
- package/lib/features/select/selection-service.d.ts.map +1 -1
- package/lib/features/select/selection-service.js +31 -45
- package/lib/features/select/selection-service.js.map +1 -1
- package/lib/features/select/selection-service.spec.js +1 -1
- package/lib/features/select/selection-service.spec.js.map +1 -1
- package/lib/features/source-model-watcher/di.config.d.ts +4 -0
- package/lib/features/{model-source-watcher → source-model-watcher}/di.config.d.ts.map +1 -1
- package/lib/features/{model-source-watcher → source-model-watcher}/di.config.js +4 -4
- package/lib/features/{model-source-watcher → source-model-watcher}/di.config.js.map +1 -1
- package/lib/features/{model-source-watcher/model-source-changed-action-handler.d.ts → source-model-watcher/source-model-changed-action-handler.d.ts} +9 -9
- package/lib/features/{model-source-watcher/model-source-changed-action-handler.d.ts.map → source-model-watcher/source-model-changed-action-handler.d.ts.map} +1 -1
- package/lib/features/{model-source-watcher/model-source-changed-action-handler.js → source-model-watcher/source-model-changed-action-handler.js} +19 -19
- package/lib/features/{model-source-watcher/model-source-changed-action-handler.js.map → source-model-watcher/source-model-changed-action-handler.js.map} +1 -1
- package/lib/features/tool-feedback/change-bounds-tool-feedback.js +1 -1
- package/lib/features/tool-feedback/change-bounds-tool-feedback.js.map +1 -1
- package/lib/features/tool-feedback/edge-edit-tool-feedback.d.ts +3 -2
- package/lib/features/tool-feedback/edge-edit-tool-feedback.d.ts.map +1 -1
- package/lib/features/tool-feedback/edge-edit-tool-feedback.js +13 -6
- package/lib/features/tool-feedback/edge-edit-tool-feedback.js.map +1 -1
- package/lib/features/tools/di.config.d.ts +9 -2
- package/lib/features/tools/di.config.d.ts.map +1 -1
- package/lib/features/tools/di.config.js +14 -3
- package/lib/features/tools/di.config.js.map +1 -1
- package/lib/features/tools/enable-default-tools-on-focus-loss.d.ts +26 -0
- package/lib/features/tools/enable-default-tools-on-focus-loss.d.ts.map +1 -0
- package/lib/features/tools/enable-default-tools-on-focus-loss.js +29 -0
- package/lib/features/tools/enable-default-tools-on-focus-loss.js.map +1 -0
- package/lib/features/validation/di.config.d.ts +0 -15
- package/lib/features/validation/di.config.d.ts.map +1 -1
- package/lib/features/validation/di.config.js +6 -4
- package/lib/features/validation/di.config.js.map +1 -1
- package/lib/features/validation/issue-marker.d.ts +11 -5
- package/lib/features/validation/issue-marker.d.ts.map +1 -1
- package/lib/features/validation/issue-marker.js +25 -5
- package/lib/features/validation/issue-marker.js.map +1 -1
- package/lib/features/validation/marker-navigator.d.ts +11 -17
- package/lib/features/validation/marker-navigator.d.ts.map +1 -1
- package/lib/features/validation/marker-navigator.js +32 -61
- package/lib/features/validation/marker-navigator.js.map +1 -1
- package/lib/features/validation/validate.d.ts +8 -19
- package/lib/features/validation/validate.d.ts.map +1 -1
- package/lib/features/validation/validate.js +29 -55
- package/lib/features/validation/validate.js.map +1 -1
- package/lib/index.d.ts +6 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +16 -15
- package/lib/index.js.map +1 -1
- package/lib/lib/model.d.ts +1 -1
- package/lib/lib/model.d.ts.map +1 -1
- package/lib/lib/model.js +3 -3
- package/lib/lib/model.js.map +1 -1
- package/lib/model-source/glsp-diagram-server.d.ts +1 -1
- package/lib/model-source/glsp-diagram-server.d.ts.map +1 -1
- package/lib/model-source/glsp-diagram-server.js +1 -1
- package/lib/model-source/glsp-diagram-server.js.map +1 -1
- package/lib/utils/layout-utils.d.ts +4 -20
- package/lib/utils/layout-utils.d.ts.map +1 -1
- package/lib/utils/layout-utils.js +1 -1
- package/lib/utils/layout-utils.js.map +1 -1
- package/lib/views/base-view-module.d.ts.map +1 -1
- package/lib/views/base-view-module.js +3 -1
- package/lib/views/base-view-module.js.map +1 -1
- package/lib/views/glsp-projection-view.d.ts +30 -0
- package/lib/views/glsp-projection-view.d.ts.map +1 -0
- package/lib/views/glsp-projection-view.js +142 -0
- package/lib/views/glsp-projection-view.js.map +1 -0
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.d.ts.map +1 -1
- package/lib/views/index.js +1 -0
- package/lib/views/index.js.map +1 -1
- package/package.json +4 -4
- package/src/base/container-modules.ts +6 -5
- package/src/base/editor-context-service.ts +15 -7
- package/src/base/model/update-model-command.ts +48 -34
- package/src/base/source-uri-aware.ts +5 -4
- package/src/features/change-bounds/movement-restrictor.ts +73 -43
- package/src/features/change-bounds/snap.ts +15 -12
- package/src/features/context-menu/selection-service-aware-context-menu-mouse-listener.ts +19 -25
- package/src/features/hover/hover.ts +2 -24
- package/src/features/layout/di.config.ts +12 -6
- package/src/features/layout/{layout-commands.spec.ts → layout-elements-action.spec.ts} +56 -48
- package/src/features/layout/{layout-commands.ts → layout-elements-action.ts} +195 -207
- package/src/features/mouse-tool/mouse-tool.ts +8 -6
- package/src/features/select/select-mouse-listener.ts +81 -1
- package/src/features/select/selection-service.spec.ts +1 -1
- package/src/features/select/selection-service.ts +37 -50
- package/src/features/{model-source-watcher → source-model-watcher}/di.config.ts +5 -5
- package/src/features/{model-source-watcher/model-source-changed-action-handler.ts → source-model-watcher/source-model-changed-action-handler.ts} +12 -12
- package/src/features/tool-feedback/change-bounds-tool-feedback.ts +1 -1
- package/src/features/tool-feedback/edge-edit-tool-feedback.ts +14 -6
- package/src/features/tools/di.config.ts +13 -2
- package/src/features/tools/enable-default-tools-on-focus-loss.ts +33 -0
- package/src/features/validation/di.config.ts +10 -7
- package/src/features/validation/issue-marker.ts +34 -12
- package/src/features/validation/marker-navigator.ts +29 -66
- package/src/features/validation/validate.ts +36 -71
- package/src/index.ts +8 -7
- package/src/lib/model.ts +1 -1
- package/src/model-source/glsp-diagram-server.ts +1 -1
- package/src/utils/layout-utils.ts +7 -27
- package/src/views/base-view-module.ts +5 -1
- package/src/views/glsp-projection-view.tsx +166 -0
- package/src/views/index.ts +2 -0
- package/lib/features/layout/layout-commands.d.ts.map +0 -1
- package/lib/features/layout/layout-commands.js.map +0 -1
- package/lib/features/layout/layout-commands.spec.d.ts +0 -3
- package/lib/features/layout/layout-commands.spec.d.ts.map +0 -1
- package/lib/features/layout/layout-commands.spec.js.map +0 -1
- package/lib/features/model-source-watcher/di.config.d.ts +0 -4
|
@@ -13,25 +13,28 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { Point } from '@eclipse-glsp/protocol';
|
|
16
|
+
import { Point, Writable } from '@eclipse-glsp/protocol';
|
|
17
17
|
import { injectable } from 'inversify';
|
|
18
18
|
import { findParentByFeature, ISnapper, isViewport, SModelElement } from 'sprotty';
|
|
19
|
-
import { WriteablePoint } from '../../utils/layout-utils';
|
|
20
19
|
|
|
20
|
+
/**
|
|
21
|
+
* A {@link ISnapper} implementation that snaps all elements onto a fixed gride size.
|
|
22
|
+
* The default grid size is 10x10 pixel.
|
|
23
|
+
* To configure a custom grid size bind the `TYPES.ISnapper` service identifier
|
|
24
|
+
* to constant value, e.g:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* bind(TYPES.ISnapper).toConstantValue(new GridSnapper({x:25 ,y:25 }));
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
21
30
|
@injectable()
|
|
22
31
|
export class GridSnapper implements ISnapper {
|
|
23
|
-
|
|
24
|
-
return 10;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get gridY(): number {
|
|
28
|
-
return 10;
|
|
29
|
-
}
|
|
32
|
+
constructor(public grid: { x: number; y: number } = { x: 10, y: 10 }) {}
|
|
30
33
|
|
|
31
34
|
snap(position: Point, element: SModelElement): Point {
|
|
32
35
|
return {
|
|
33
|
-
x: Math.round(position.x / this.
|
|
34
|
-
y: Math.round(position.y / this.
|
|
36
|
+
x: Math.round(position.x / this.grid.x) * this.grid.x,
|
|
37
|
+
y: Math.round(position.y / this.grid.y) * this.grid.y
|
|
35
38
|
};
|
|
36
39
|
}
|
|
37
40
|
}
|
|
@@ -46,7 +49,7 @@ export class GridSnapper implements ISnapper {
|
|
|
46
49
|
*/
|
|
47
50
|
export class PointPositionUpdater {
|
|
48
51
|
protected lastDragPosition?: Point;
|
|
49
|
-
protected positionDelta:
|
|
52
|
+
protected positionDelta: Writable<Point> = { x: 0, y: 0 };
|
|
50
53
|
|
|
51
54
|
constructor(protected snapper?: ISnapper) {}
|
|
52
55
|
|
|
@@ -15,53 +15,47 @@
|
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
import { Action } from '@eclipse-glsp/protocol';
|
|
17
17
|
import { inject, injectable, optional } from 'inversify';
|
|
18
|
-
import {
|
|
19
|
-
ContextMenuProviderRegistry,
|
|
20
|
-
findParentByFeature,
|
|
21
|
-
IContextMenuServiceProvider,
|
|
22
|
-
isSelectable,
|
|
23
|
-
MouseListener,
|
|
24
|
-
SModelElement
|
|
25
|
-
} from 'sprotty';
|
|
18
|
+
import { ContextMenuProviderRegistry, IContextMenuServiceProvider, MouseListener, SModelElement } from 'sprotty';
|
|
26
19
|
import { FocusStateChangedAction } from '../../base/actions/focus-change-action';
|
|
27
20
|
import { TYPES } from '../../base/types';
|
|
28
21
|
import { SelectionService } from '../select/selection-service';
|
|
29
22
|
|
|
30
23
|
@injectable()
|
|
31
24
|
export class SelectionServiceAwareContextMenuMouseListener extends MouseListener {
|
|
32
|
-
@inject(TYPES.IContextMenuServiceProvider)
|
|
33
|
-
@
|
|
34
|
-
|
|
25
|
+
@inject(TYPES.IContextMenuServiceProvider)
|
|
26
|
+
@optional()
|
|
27
|
+
protected readonly contextMenuService?: IContextMenuServiceProvider;
|
|
28
|
+
|
|
29
|
+
@inject(TYPES.IContextMenuProviderRegistry)
|
|
30
|
+
@optional()
|
|
31
|
+
protected readonly menuProvider?: ContextMenuProviderRegistry;
|
|
32
|
+
|
|
33
|
+
@inject(TYPES.SelectionService)
|
|
34
|
+
protected selectionService: SelectionService;
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Opens the context menu
|
|
37
|
+
* Opens the context menu.
|
|
38
38
|
*/
|
|
39
|
-
override
|
|
40
|
-
|
|
41
|
-
return this.openContextMenu(event, target);
|
|
42
|
-
}
|
|
43
|
-
return [];
|
|
39
|
+
override contextMenu(target: SModelElement, event: MouseEvent): (Action | Promise<Action>)[] {
|
|
40
|
+
return this.openContextMenu(target, event);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
/**
|
|
47
44
|
* Opens the context menu.
|
|
48
45
|
*
|
|
49
|
-
* - query the element on the click-target
|
|
50
|
-
* - select the element
|
|
51
46
|
* - query the context menu service and the context menu elements
|
|
52
47
|
* - show the context menu
|
|
53
48
|
* - send a focus state change to indicate that the diagram becomes inactive, once the context menu is shown
|
|
54
49
|
*
|
|
55
50
|
* When the context menu is closed, we focus the diagram element again.
|
|
56
51
|
*/
|
|
57
|
-
protected openContextMenu(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (selectableTarget) {
|
|
61
|
-
selectableTarget.selected = true;
|
|
62
|
-
this.selectionService.updateSelection(target.root, [selectableTarget.id], []);
|
|
52
|
+
protected openContextMenu(target: SModelElement, event: MouseEvent): Promise<Action>[] {
|
|
53
|
+
if (!this.contextMenuService || !this.menuProvider) {
|
|
54
|
+
return [];
|
|
63
55
|
}
|
|
64
56
|
|
|
57
|
+
const mousePosition = { x: event.x, y: event.y };
|
|
58
|
+
|
|
65
59
|
const result = Promise.all([this.contextMenuService(), this.menuProvider.getItems(target.root, mousePosition)])
|
|
66
60
|
.then(([menuService, menuItems]) => menuService.show(menuItems, mousePosition, () => this.focusEventTarget(event)))
|
|
67
61
|
.then((): Action => FocusStateChangedAction.create(false));
|
|
@@ -23,20 +23,11 @@ import {
|
|
|
23
23
|
SModelRootSchema
|
|
24
24
|
} from '@eclipse-glsp/protocol';
|
|
25
25
|
import { injectable } from 'inversify';
|
|
26
|
-
import {
|
|
27
|
-
EMPTY_ROOT,
|
|
28
|
-
HoverFeedbackAction,
|
|
29
|
-
HoverMouseListener,
|
|
30
|
-
IActionHandler,
|
|
31
|
-
ICommand,
|
|
32
|
-
SIssueMarker,
|
|
33
|
-
SIssueSeverity,
|
|
34
|
-
SModelElement
|
|
35
|
-
} from 'sprotty';
|
|
26
|
+
import { EMPTY_ROOT, HoverFeedbackAction, HoverMouseListener, IActionHandler, ICommand, SModelElement } from 'sprotty';
|
|
36
27
|
import { FocusStateChangedAction } from '../../base/actions/focus-change-action';
|
|
37
28
|
import { EnableDefaultToolsAction, EnableToolsAction } from '../../base/tool-manager/tool-actions';
|
|
38
29
|
import { EdgeCreationTool } from '../tools/edge-creation-tool';
|
|
39
|
-
import { GIssueMarker } from '../validation/issue-marker';
|
|
30
|
+
import { getSeverity, GIssueMarker } from '../validation/issue-marker';
|
|
40
31
|
@injectable()
|
|
41
32
|
export class GlspHoverMouseListener extends HoverMouseListener implements IActionHandler {
|
|
42
33
|
protected enableHover = true;
|
|
@@ -117,16 +108,3 @@ export class GlspHoverMouseListener extends HoverMouseListener implements IActio
|
|
|
117
108
|
return bounds;
|
|
118
109
|
}
|
|
119
110
|
}
|
|
120
|
-
|
|
121
|
-
export function getSeverity(marker: SIssueMarker): SIssueSeverity {
|
|
122
|
-
let currentSeverity: SIssueSeverity = 'info';
|
|
123
|
-
for (const severity of marker.issues.map(s => s.severity)) {
|
|
124
|
-
if (severity === 'error') {
|
|
125
|
-
return severity;
|
|
126
|
-
}
|
|
127
|
-
if (severity === 'warning' && currentSeverity === 'info') {
|
|
128
|
-
currentSeverity = severity;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return currentSeverity;
|
|
132
|
-
}
|
|
@@ -14,19 +14,25 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
import { ContainerModule } from 'inversify';
|
|
17
|
-
import {
|
|
17
|
+
import { configureActionHandler, configureLayout, HBoxLayouter, VBoxLayouter } from 'sprotty';
|
|
18
18
|
import { FreeFormLayouter } from './freeform-layout';
|
|
19
19
|
import { HBoxLayouterExt } from './hbox-layout';
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
AlignElementsAction,
|
|
22
|
+
AlignElementsActionHandler,
|
|
23
|
+
ResizeElementsAction,
|
|
24
|
+
ResizeElementsActionHandler
|
|
25
|
+
} from './layout-elements-action';
|
|
21
26
|
import { VBoxLayouterExt } from './vbox-layout';
|
|
22
27
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
const layoutModule = new ContainerModule((bind, _unbind, isBound, rebind) => {
|
|
29
|
+
const context = { bind, isBound };
|
|
30
|
+
configureActionHandler(context, ResizeElementsAction.KIND, ResizeElementsActionHandler);
|
|
31
|
+
configureActionHandler(context, AlignElementsAction.KIND, AlignElementsActionHandler);
|
|
26
32
|
|
|
27
33
|
rebind(VBoxLayouter).to(VBoxLayouterExt);
|
|
28
34
|
rebind(HBoxLayouter).to(HBoxLayouterExt);
|
|
29
35
|
configureLayout({ bind, isBound }, FreeFormLayouter.KIND, FreeFormLayouter);
|
|
30
36
|
});
|
|
31
37
|
|
|
32
|
-
export default
|
|
38
|
+
export default layoutModule;
|
|
@@ -48,13 +48,12 @@ import { SelectionService } from '../select/selection-service';
|
|
|
48
48
|
import { FeedbackActionDispatcher } from '../tool-feedback/feedback-action-dispatcher';
|
|
49
49
|
import {
|
|
50
50
|
AlignElementsAction,
|
|
51
|
-
|
|
51
|
+
AlignElementsActionHandler,
|
|
52
52
|
Alignment,
|
|
53
|
-
Reduce,
|
|
54
53
|
ResizeDimension,
|
|
55
54
|
ResizeElementsAction,
|
|
56
|
-
|
|
57
|
-
} from './layout-
|
|
55
|
+
ResizeElementsActionHandler
|
|
56
|
+
} from './layout-elements-action';
|
|
58
57
|
|
|
59
58
|
class MockActionDispatcher implements IActionDispatcher {
|
|
60
59
|
constructor(public dispatchedActions: Action[] = []) {}
|
|
@@ -71,14 +70,21 @@ class MockActionDispatcher implements IActionDispatcher {
|
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
|
|
73
|
+
class MockSelectionService extends SelectionService {
|
|
74
|
+
constructor(public modelRoot: SModelRoot) {
|
|
75
|
+
super();
|
|
76
|
+
}
|
|
77
|
+
override getModelRoot(): Readonly<SModelRoot> {
|
|
78
|
+
return this.modelRoot;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Generic Test setup
|
|
74
83
|
const container = new Container();
|
|
75
84
|
container.load(defaultModule);
|
|
76
85
|
container.bind(TYPES.IFeedbackActionDispatcher).to(FeedbackActionDispatcher).inSingletonScope();
|
|
77
|
-
container.bind(SelectionService).toSelf().inSingletonScope();
|
|
78
|
-
container.bind(TYPES.SelectionService).toService(SelectionService);
|
|
79
86
|
container.rebind(TYPES.IModelFactory).to(SGraphFactory).inSingletonScope();
|
|
80
87
|
const graphFactory = container.get<SGraphFactory>(TYPES.IModelFactory);
|
|
81
|
-
const selectionService = container.get<SelectionService>(TYPES.SelectionService);
|
|
82
88
|
|
|
83
89
|
const actionDispatcher = new MockActionDispatcher();
|
|
84
90
|
|
|
@@ -125,16 +131,26 @@ const context: CommandExecutionContext = {
|
|
|
125
131
|
const defaultSize = { height: 10, width: 10 };
|
|
126
132
|
|
|
127
133
|
describe('AlignElementsCommand', () => {
|
|
128
|
-
|
|
134
|
+
let handler: AlignElementsActionHandler;
|
|
135
|
+
const setModel = (newModel: SModelRoot): void => {
|
|
136
|
+
handler['selectionService'] = new MockSelectionService(newModel);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
beforeEach(() => {
|
|
129
140
|
actionDispatcher.dispatchedActions = [];
|
|
141
|
+
|
|
142
|
+
handler = new AlignElementsActionHandler();
|
|
143
|
+
handler['actionDispatcher'] = actionDispatcher;
|
|
144
|
+
});
|
|
145
|
+
it('should align all elements left', () => {
|
|
130
146
|
const newModel = initModel([
|
|
131
147
|
{ elementId: 'node1', newPosition: { x: 111, y: 111 }, newSize: defaultSize },
|
|
132
148
|
{ elementId: 'node2', newPosition: { x: 222, y: 222 }, newSize: defaultSize },
|
|
133
149
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
134
150
|
]);
|
|
135
151
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Left });
|
|
136
|
-
|
|
137
|
-
|
|
152
|
+
setModel(newModel);
|
|
153
|
+
handler.handle(action);
|
|
138
154
|
|
|
139
155
|
assertAllBounds(
|
|
140
156
|
new Map([
|
|
@@ -146,16 +162,14 @@ describe('AlignElementsCommand', () => {
|
|
|
146
162
|
});
|
|
147
163
|
|
|
148
164
|
it('should align all elements right', () => {
|
|
149
|
-
actionDispatcher.dispatchedActions = [];
|
|
150
165
|
const newModel = initModel([
|
|
151
166
|
{ elementId: 'node1', newPosition: { x: 111, y: 111 }, newSize: defaultSize },
|
|
152
167
|
{ elementId: 'node2', newPosition: { x: 222, y: 222 }, newSize: defaultSize },
|
|
153
168
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
154
169
|
]);
|
|
155
170
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Right });
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
setModel(newModel);
|
|
172
|
+
handler.handle(action);
|
|
159
173
|
assertAllBounds(
|
|
160
174
|
new Map([
|
|
161
175
|
['node1', { x: 333, y: 111, width: defaultSize.width, height: defaultSize.height }],
|
|
@@ -173,8 +187,8 @@ describe('AlignElementsCommand', () => {
|
|
|
173
187
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
174
188
|
]);
|
|
175
189
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Center });
|
|
176
|
-
|
|
177
|
-
|
|
190
|
+
setModel(newModel);
|
|
191
|
+
handler.handle(action);
|
|
178
192
|
|
|
179
193
|
assertAllBounds(
|
|
180
194
|
new Map([
|
|
@@ -186,15 +200,14 @@ describe('AlignElementsCommand', () => {
|
|
|
186
200
|
});
|
|
187
201
|
|
|
188
202
|
it('should align all elements top', () => {
|
|
189
|
-
actionDispatcher.dispatchedActions = [];
|
|
190
203
|
const newModel = initModel([
|
|
191
204
|
{ elementId: 'node1', newPosition: { x: 111, y: 111 }, newSize: defaultSize },
|
|
192
205
|
{ elementId: 'node2', newPosition: { x: 222, y: 222 }, newSize: defaultSize },
|
|
193
206
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
194
207
|
]);
|
|
195
208
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Top });
|
|
196
|
-
|
|
197
|
-
|
|
209
|
+
setModel(newModel);
|
|
210
|
+
handler.handle(action);
|
|
198
211
|
|
|
199
212
|
assertAllBounds(
|
|
200
213
|
new Map([
|
|
@@ -206,15 +219,14 @@ describe('AlignElementsCommand', () => {
|
|
|
206
219
|
});
|
|
207
220
|
|
|
208
221
|
it('should align all elements bottom', () => {
|
|
209
|
-
actionDispatcher.dispatchedActions = [];
|
|
210
222
|
const newModel = initModel([
|
|
211
223
|
{ elementId: 'node1', newPosition: { x: 111, y: 111 }, newSize: defaultSize },
|
|
212
224
|
{ elementId: 'node2', newPosition: { x: 222, y: 222 }, newSize: defaultSize },
|
|
213
225
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
214
226
|
]);
|
|
215
227
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Bottom });
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
setModel(newModel);
|
|
229
|
+
handler.handle(action);
|
|
218
230
|
|
|
219
231
|
assertAllBounds(
|
|
220
232
|
new Map([
|
|
@@ -226,15 +238,14 @@ describe('AlignElementsCommand', () => {
|
|
|
226
238
|
});
|
|
227
239
|
|
|
228
240
|
it('should align all elements middle', () => {
|
|
229
|
-
actionDispatcher.dispatchedActions = [];
|
|
230
241
|
const newModel = initModel([
|
|
231
242
|
{ elementId: 'node1', newPosition: { x: 111, y: 111 }, newSize: defaultSize },
|
|
232
243
|
{ elementId: 'node2', newPosition: { x: 222, y: 222 }, newSize: defaultSize },
|
|
233
244
|
{ elementId: 'node3', newPosition: { x: 333, y: 333 }, newSize: defaultSize }
|
|
234
245
|
]);
|
|
235
246
|
const action = AlignElementsAction.create({ elementIds: ['node1', 'node2', 'node3'], alignment: Alignment.Middle });
|
|
236
|
-
|
|
237
|
-
|
|
247
|
+
setModel(newModel);
|
|
248
|
+
handler.handle(action);
|
|
238
249
|
|
|
239
250
|
assertAllBounds(
|
|
240
251
|
new Map([
|
|
@@ -247,8 +258,18 @@ describe('AlignElementsCommand', () => {
|
|
|
247
258
|
});
|
|
248
259
|
|
|
249
260
|
describe('ResizeElementsCommand', () => {
|
|
250
|
-
|
|
261
|
+
let handler: ResizeElementsActionHandler;
|
|
262
|
+
const setModel = (newModel: SModelRoot): void => {
|
|
263
|
+
handler['selectionService'] = new MockSelectionService(newModel);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
beforeEach(() => {
|
|
251
267
|
actionDispatcher.dispatchedActions = [];
|
|
268
|
+
|
|
269
|
+
handler = new ResizeElementsActionHandler();
|
|
270
|
+
handler['actionDispatcher'] = actionDispatcher;
|
|
271
|
+
});
|
|
272
|
+
it('should make same width as last', () => {
|
|
252
273
|
const newModel = initModel([
|
|
253
274
|
{ elementId: 'node1', newPosition: { x: 100, y: 100 }, newSize: { height: 10, width: 10 } },
|
|
254
275
|
{ elementId: 'node2', newPosition: { x: 100, y: 200 }, newSize: { height: 20, width: 20 } },
|
|
@@ -257,10 +278,10 @@ describe('ResizeElementsCommand', () => {
|
|
|
257
278
|
const action = ResizeElementsAction.create({
|
|
258
279
|
elementIds: ['node1', 'node2', 'node3'],
|
|
259
280
|
dimension: ResizeDimension.Width,
|
|
260
|
-
|
|
281
|
+
reduceFunction: 'last'
|
|
261
282
|
});
|
|
262
|
-
|
|
263
|
-
|
|
283
|
+
setModel(newModel);
|
|
284
|
+
handler.handle(action);
|
|
264
285
|
|
|
265
286
|
// resize is keeping the center, so the X moves by diff / 2
|
|
266
287
|
assertAllBoundsInChangeBounds(
|
|
@@ -273,7 +294,6 @@ describe('ResizeElementsCommand', () => {
|
|
|
273
294
|
});
|
|
274
295
|
|
|
275
296
|
it('should make same height as last', () => {
|
|
276
|
-
actionDispatcher.dispatchedActions = [];
|
|
277
297
|
const newModel = initModel([
|
|
278
298
|
{ elementId: 'node1', newPosition: { x: 100, y: 100 }, newSize: { height: 10, width: 10 } },
|
|
279
299
|
{ elementId: 'node2', newPosition: { x: 100, y: 200 }, newSize: { height: 20, width: 20 } },
|
|
@@ -282,10 +302,10 @@ describe('ResizeElementsCommand', () => {
|
|
|
282
302
|
const action = ResizeElementsAction.create({
|
|
283
303
|
elementIds: ['node1', 'node2', 'node3'],
|
|
284
304
|
dimension: ResizeDimension.Height,
|
|
285
|
-
|
|
305
|
+
reduceFunction: 'last'
|
|
286
306
|
});
|
|
287
|
-
|
|
288
|
-
|
|
307
|
+
setModel(newModel);
|
|
308
|
+
handler.handle(action);
|
|
289
309
|
|
|
290
310
|
// resize is keeping the center, so the Y moves by diff / 2
|
|
291
311
|
assertAllBoundsInChangeBounds(
|
|
@@ -298,7 +318,6 @@ describe('ResizeElementsCommand', () => {
|
|
|
298
318
|
});
|
|
299
319
|
|
|
300
320
|
it('should make same width and height as last', () => {
|
|
301
|
-
actionDispatcher.dispatchedActions = [];
|
|
302
321
|
const newModel = initModel([
|
|
303
322
|
{ elementId: 'node1', newPosition: { x: 100, y: 100 }, newSize: { height: 10, width: 10 } },
|
|
304
323
|
{ elementId: 'node2', newPosition: { x: 100, y: 200 }, newSize: { height: 20, width: 20 } },
|
|
@@ -307,10 +326,10 @@ describe('ResizeElementsCommand', () => {
|
|
|
307
326
|
const action = ResizeElementsAction.create({
|
|
308
327
|
elementIds: ['node1', 'node2', 'node3'],
|
|
309
328
|
dimension: ResizeDimension.Width_And_Height,
|
|
310
|
-
|
|
329
|
+
reduceFunction: 'last'
|
|
311
330
|
});
|
|
312
|
-
|
|
313
|
-
|
|
331
|
+
setModel(newModel);
|
|
332
|
+
handler.handle(action);
|
|
314
333
|
|
|
315
334
|
// resize is keeping the center, so the Y moves by diff / 2
|
|
316
335
|
assertAllBoundsInChangeBounds(
|
|
@@ -329,17 +348,6 @@ function initModel(elementAndBounds: ElementAndBounds[]): SModelRoot {
|
|
|
329
348
|
return setBoundsCommand.execute(context) as SModelRoot;
|
|
330
349
|
}
|
|
331
350
|
|
|
332
|
-
function newContext(root: SModelRoot): CommandExecutionContext {
|
|
333
|
-
return {
|
|
334
|
-
root: root,
|
|
335
|
-
modelFactory: graphFactory,
|
|
336
|
-
duration: 0,
|
|
337
|
-
modelChanged: undefined!,
|
|
338
|
-
logger: new ConsoleLogger(),
|
|
339
|
-
syncer: new AnimationFrameSyncer()
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
|
|
343
351
|
function assertAllBounds(allBounds: Map<string, Bounds>): void {
|
|
344
352
|
allBounds.forEach((bounds, nodeId) => assertBounds(nodeId, bounds));
|
|
345
353
|
}
|