svg-layout-designer-react/src/Components/Editor/Behaviors/PushBehaviors.ts
Eric Nguyen 18cbacaca1 Merged PR 196: Implement Vertical orientation + Upgrade Heroicons to 2.0
Implémenter l'orientation verticale

Modifier l'effet de append

Implementer RigidBody

Implementer Flex et simplex

Implémenter Push

Implémenter Swap

Implement MinMaxHeight without behaviors

Fix Margin for Height

Implement PositionReference

Fix dimension vertical position inside children

Add orientation change in form

Implement sortChildren

Implement Anchor

Fix warning message on overlapping

Fix minimap when root container is vertical

#7287
#7288
#7289
#7290
#7291
#7292
#7294
#7295
#7296
#7297
#7298
#7299
#7300
#7301
#7302
2022-09-28 16:07:56 +00:00

139 lines
4.3 KiB
TypeScript

import { IContainerModel } from '../../../Interfaces/IContainerModel';
import { Orientation } from '../../../Interfaces/Orientation';
import { ReversePairwise } from '../../../utils/itertools';
import { Flex } from './FlexBehaviors';
/**
* Try to push the siblings
* @param container
* @returns
*/
export function ApplyPush(container: IContainerModel, parent: IContainerModel): IContainerModel {
if (parent.children.length <= 1) {
return container;
}
const children = parent.children;
const isHorizontal = parent.properties.orientation === Orientation.Horizontal;
if (isHorizontal) {
PushContainersHorizontally(container, children);
} else {
PushContainersVertically(container, children);
}
Flex(container, parent);
return container;
}
export function PushContainersHorizontally(container: IContainerModel, children: IContainerModel[]): IContainerModel {
const prevIndex = children.length - 2;
const prev: IContainerModel = children[prevIndex];
const isOverlapping = prev.properties.x + prev.properties.width > container.properties.x;
if (!isOverlapping) {
return container;
}
// find hole
let lastContainer: IContainerModel | null = null;
let space: number = 0;
while (space.toFixed(2) < container.properties.width.toFixed(2)) {
// FIXME: possible infinite loop due to floating point
// FIXME: A fix was applied using toFixed(2).
// FIXME: A coverture check must be done to ensure that all scenarios are covered
const it = ReversePairwise<IContainerModel>(children.filter(child => child !== container));
for (const { cur, next } of it) {
const hasSpaceBetween = next.properties.x + next.properties.width < cur.properties.x;
if (hasSpaceBetween) {
lastContainer = cur;
space = cur.properties.x - (next.properties.x + next.properties.width);
break;
}
}
if (lastContainer === null) {
// no space between
break;
}
const indexLastContainer = children.indexOf(lastContainer);
for (let i = indexLastContainer; i <= children.length - 2; i++) {
const sibling = children[i];
sibling.properties.x -= space;
}
}
const hasNoSpaceBetween = lastContainer === null;
if (hasNoSpaceBetween) {
// test gap between the left of the parent and the first container
space = children[0].properties.x;
if (space > 0) {
for (let i = 0; i <= children.length - 2; i++) {
const sibling = children[i];
sibling.properties.x -= space;
}
return container;
}
}
return container;
}
export function PushContainersVertically(container: IContainerModel, children: IContainerModel[]): IContainerModel {
const prevIndex = children.length - 2;
const prev: IContainerModel = children[prevIndex];
const isOverlapping = prev.properties.y + prev.properties.height > container.properties.y;
if (!isOverlapping) {
return container;
}
// find hole
let lastContainer: IContainerModel | null = null;
let space: number = 0;
while (space.toFixed(2) < container.properties.height.toFixed(2)) {
// FIXME: possible infinite loop due to floating point
// FIXME: A fix was applied using toFixed(2).
// FIXME: A coverture check must be done to ensure that all scenarios are covered
const it = ReversePairwise<IContainerModel>(children.filter(child => child !== container));
for (const { cur, next } of it) {
const hasSpaceBetween = next.properties.y + next.properties.height < cur.properties.y;
if (hasSpaceBetween) {
lastContainer = cur;
space = cur.properties.y - (next.properties.y + next.properties.height);
break;
}
}
if (lastContainer === null) {
// no space between
break;
}
const indexLastContainer = children.indexOf(lastContainer);
for (let i = indexLastContainer; i <= children.length - 2; i++) {
const sibling = children[i];
sibling.properties.y -= space;
}
}
const hasNoSpaceBetween = lastContainer === null;
if (hasNoSpaceBetween) {
// test gap between the left of the parent and the first container
space = children[0].properties.y;
if (space > 0) {
for (let i = 0; i <= children.length - 2; i++) {
const sibling = children[i];
sibling.properties.y -= space;
}
return container;
}
}
return container;
}