Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[956] Implement bordered snap to parent container
The border node enters its parent container with 8px. Bug: #956 Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
- Loading branch information
Showing
11 changed files
with
456 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
doc/adrs/044_add_border_node_snap_to_container_algorithm.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
= ADR-44 - Use border node "snap to parent container" algorithm | ||
|
||
== Context | ||
|
||
On the front end, consider a diagram containing nodes with border nodes. | ||
|
||
The user has the abilty to move the border nodes on a side of the parent rectangle node or onto another side. | ||
|
||
Until now, the border node is considered as any node and consequently the user has the ability to move the border node inside the parent node and only inside. | ||
|
||
== Decision | ||
|
||
A "snap to parent rectangle" is added. | ||
It is used by the front end code. | ||
|
||
Now, when the user moves the border node, it is moved only on the border of the parent node, outside the parent node. | ||
|
||
An 8px offset is used to have the border node entering the parent node. | ||
|
||
=== Algorithm details | ||
|
||
When the user is dragging the border node, to determine the side on which the border node will snap, the algorithm calculates the distance between the center of the dragged border node to each side segment of the parent node. The snap is done on the closest parent node side. | ||
|
||
Then the offset is applied on the border node to have the border node entering the parent node | ||
|
||
== Status | ||
|
||
WIP | ||
|
||
== Consequences |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
frontend/src/diagram/sprotty/__tests__/borderNodes.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2022 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
import { httpOrigin } from 'common/URL'; | ||
import 'reflect-metadata'; | ||
import { SNode } from 'sprotty'; | ||
import { Point } from 'sprotty-protocol/'; | ||
import { convertDiagram } from '../convertDiagram'; | ||
import { BorderNode } from '../Diagram.types'; | ||
import { SiriusDragAndDropMouseListener } from '../siriusDragAndDropMouseListener'; | ||
import { siriusWebDiagram } from './siriusWebDiagram'; | ||
|
||
describe('Border node positioning', () => { | ||
it('snaps the border node', () => { | ||
const sprottyDiagram = convertDiagram(siriusWebDiagram, httpOrigin, false); | ||
|
||
const sprottyNode: SNode = <SNode>sprottyDiagram.children[1]; | ||
|
||
const borderNode: BorderNode = <BorderNode>sprottyNode.children.filter((value) => { | ||
return value instanceof BorderNode; | ||
})[0]; | ||
|
||
// border node position when its center is positionned at the parent upper left corner(origin)) | ||
const borderNodeOrigin: Point = { x: -borderNode.size.width / 2, y: -borderNode.size.height / 2 }; | ||
const parentWidth: number = sprottyNode.size.width; | ||
const parentHeight: number = sprottyNode.size.height; | ||
|
||
const siriusDragAndDropMouseListener: SiriusDragAndDropMouseListener = new SiriusDragAndDropMouseListener(); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x - 10, y: borderNodeOrigin.y - 5 }, borderNode, false) | ||
).toStrictEqual({ x: -52, y: -20 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x - 10, y: borderNodeOrigin.y - 15 }, borderNode, false) | ||
).toStrictEqual({ x: -30, y: -32 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x + 50, y: borderNodeOrigin.y - 25 }, borderNode, false) | ||
).toStrictEqual({ x: 20, y: -32 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x + 50, y: borderNodeOrigin.y + 5 }, borderNode, false) | ||
).toStrictEqual({ x: 20, y: -32 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth + 5, y: borderNodeOrigin.y - 10 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 250, y: -32 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth + 15, y: borderNodeOrigin.y - 10 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 272, y: -20 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth + 15, y: borderNodeOrigin.y + 50 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 272, y: 30 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth - 5, y: borderNodeOrigin.y + 50 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 272, y: 30 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth + 15, y: borderNodeOrigin.y + parentHeight + 10 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 272, y: 160 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth + 10, y: borderNodeOrigin.y + parentHeight + 15 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 250, y: 172 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth / 2, y: borderNodeOrigin.y + parentHeight - 5 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 110, y: 172 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + parentWidth / 2, y: borderNodeOrigin.y + parentHeight + 5 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: 110, y: 172 }); | ||
|
||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x - 5, y: borderNodeOrigin.y + 10 }, borderNode, false) | ||
).toStrictEqual({ x: -52, y: -10 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x - 10, y: borderNodeOrigin.y + 5 }, borderNode, false) | ||
).toStrictEqual({ x: -52, y: -15 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x + 10, y: borderNodeOrigin.y + parentHeight / 2 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: -52, y: 70 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap( | ||
{ x: borderNodeOrigin.x - 10, y: borderNodeOrigin.y + parentHeight / 2 }, | ||
borderNode, | ||
false | ||
) | ||
).toStrictEqual({ x: -52, y: 70 }); | ||
expect( | ||
siriusDragAndDropMouseListener.snap({ x: borderNodeOrigin.x - 10, y: borderNodeOrigin.y - 5 }, borderNode, false) | ||
).toStrictEqual({ x: -52, y: -20 }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.