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
457 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
32 changes: 32 additions & 0 deletions
32
doc/adrs/041_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,32 @@ | ||
= ADR-41 - 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 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 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 25% offset is used to have the border node entering the parent node. | ||
|
||
=== Algorithm details | ||
|
||
To determines the side to snap, the algorithm calculates the distance between the center of the "under moved" border node and each border segment border of the parent node. The snap is done on the closest border. | ||
|
||
Then the offset is applied to have the border node entering the parent node | ||
* For north and south borders, 25% is applied and the height of the border node. | ||
* For east and west borders, 25% is applied and the width of the border 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.