Skip to content

Commit

Permalink
feat(space-tool): consider attachers when getting constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Aug 14, 2020
1 parent dd379fa commit f1e760e
Show file tree
Hide file tree
Showing 3 changed files with 343 additions and 5 deletions.
63 changes: 59 additions & 4 deletions lib/features/space-tool/SpaceTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import {
isNumber
} from 'min-dash';

import { asTRBL } from '../../layout/LayoutUtil';
import {
asTRBL,
getMid
} from '../../layout/LayoutUtil';

import { getBBox } from '../../util/Elements';

Expand Down Expand Up @@ -361,24 +364,33 @@ function getSpaceToolConstraints(elements, axis, direction, start, minDimensions
max;

forEach(resizingShapes, function(resizingShape) {
var attachers = resizingShape.attachers,
children = resizingShape.children;

var resizingShapeBBox = asTRBL(resizingShape);

// find children that are not moving or resizing
var nonMovingResizingChildren = filter(resizingShape.children, function(child) {
var nonMovingResizingChildren = filter(children, function(child) {
return !isConnection(child) &&
!isLabel(child) &&
!includes(movingShapes, child) &&
!includes(resizingShapes, child);
});

// find children that are moving
var movingChildren = filter(resizingShape.children, function(child) {
var movingChildren = filter(children, function(child) {
return !isConnection(child) && !isLabel(child) && includes(movingShapes, child);
});

var minOrMax,
nonMovingResizingChildrenBBox,
movingChildrenBBox;
movingChildrenBBox,
movingAttachers = [],
nonMovingAttachers = [],
movingAttachersBBox,
movingAttachersConstraint,
nonMovingAttachersBBox,
nonMovingAttachersConstraint;

if (nonMovingResizingChildren.length) {
nonMovingResizingChildrenBBox = addPadding(asTRBL(getBBox(nonMovingResizingChildren)));
Expand Down Expand Up @@ -416,9 +428,52 @@ function getSpaceToolConstraints(elements, axis, direction, start, minDimensions
}
}

if (attachers && attachers.length) {
attachers.forEach(function(attacher) {
if (movingShapes.indexOf(attacher) !== -1) {
movingAttachers.push(attacher);
} else {
nonMovingAttachers.push(attacher);
}
});

if (movingAttachers.length) {
movingAttachersBBox = asTRBL(getBBox(movingAttachers.map(getMid)));

movingAttachersConstraint = resizingShapeBBox[ DIRECTION_TO_TRBL[ DIRECTION_TO_OPPOSITE[ direction ] ] ]
- (movingAttachersBBox[ DIRECTION_TO_TRBL[ DIRECTION_TO_OPPOSITE[ direction ] ] ] - start);
}

if (nonMovingAttachers.length) {
nonMovingAttachersBBox = asTRBL(getBBox(nonMovingAttachers.map(getMid)));

nonMovingAttachersConstraint = nonMovingAttachersBBox[ DIRECTION_TO_TRBL[ direction ] ]
- (resizingShapeBBox[ DIRECTION_TO_TRBL[ direction ] ] - start);
}

if (direction === 'n') {
minOrMax = Math.min(movingAttachersConstraint || Infinity, nonMovingAttachersConstraint || Infinity);

spaceToolConstraints.bottom = max = isNumber(max) ? Math.min(max, minOrMax) : minOrMax;
} else if (direction === 'w') {
minOrMax = Math.min(movingAttachersConstraint || Infinity, nonMovingAttachersConstraint || Infinity);

spaceToolConstraints.right = max = isNumber(max) ? Math.min(max, minOrMax) : minOrMax;
} else if (direction === 's') {
minOrMax = Math.max(movingAttachersConstraint || -Infinity, nonMovingAttachersConstraint || -Infinity);

spaceToolConstraints.top = min = isNumber(min) ? Math.max(min, minOrMax) : minOrMax;
} else if (direction === 'e') {
minOrMax = Math.max(movingAttachersConstraint || -Infinity, nonMovingAttachersConstraint || -Infinity);

spaceToolConstraints.left = min = isNumber(min) ? Math.max(min, minOrMax) : minOrMax;
}
}

var resizingShapeMinDimensions = minDimensions && minDimensions[ resizingShape.id ];

if (resizingShapeMinDimensions) {

if (direction === 'n') {
minOrMax = start +
resizingShape[ AXIS_TO_DIMENSION [ axis ] ] -
Expand Down
281 changes: 281 additions & 0 deletions test/spec/features/space-tool/SpaceToolSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,287 @@ describe('features/space-tool', function() {
});


describe('attachers', function() {

var parentShape3;

beforeEach(inject(function(canvas, elementFactory) {
parentShape3 = elementFactory.createShape({
id: 'parent3',
x: 1100, y: 500,
width: 250, height: 150
});

canvas.addShape(parentShape3);
}));


describe('moving attachers', function() {

it('should consider attachers when resizing shape (n)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x - 25,
y: parentShape3.y + parentShape3.height - 75,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 0, y: 640 }));

dragging.move(canvasEvent({ x: 0, y: 1000 }, keyModifier));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 550,
width: 250,
height: 100
});
}
));


it('should consider attachers when resizing shape (w)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x + parentShape3.width - 75,
y: parentShape3.y - 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 1340, y: 0 }));

dragging.move(canvasEvent({ x: 2000, y: 0 }, keyModifier));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1150,
y: 500,
width: 200,
height: 150
});
}
));


it('should consider attachers when resizing shape (s)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x - 25,
y: parentShape3.y + 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 0, y: 510 }));

dragging.move(canvasEvent({ x: 0, y: 0 }));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 500,
width: 250,
height: 100
});
}
));


it('should consider attachers when resizing shape (e)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x + 25,
y: parentShape3.y - 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 1110, y: 0 }));

dragging.move(canvasEvent({ x: 0, y: 0 }));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 500,
width: 200,
height: 150
});
}
));

});


describe('non-moving attachers', function() {

it('should consider attachers when resizing shape (n)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x - 25,
y: parentShape3.y + parentShape3.height - 75,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 0, y: 510 }));

dragging.move(canvasEvent({ x: 0, y: 1000 }, keyModifier));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 600,
width: 250,
height: 50
});
}
));


it('should consider attachers when resizing shape (w)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x + parentShape3.width - 75,
y: parentShape3.y - 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 1110, y: 0 }));

dragging.move(canvasEvent({ x: 2000, y: 0 }, keyModifier));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1300,
y: 500,
width: 50,
height: 150
});
}
));


it('should consider attachers when resizing shape (s)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x - 25,
y: parentShape3.y + 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 0, y: 640 }));

dragging.move(canvasEvent({ x: 0, y: 0 }));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 500,
width: 250,
height: 50
});
}
));


it('should consider attachers when resizing shape (e)', inject(
function(canvas, dragging, elementFactory, spaceTool) {

// given
var attacher = elementFactory.createShape({
id: 'attacher',
x: parentShape3.x + 25,
y: parentShape3.y - 25,
width: 50, height: 50,
host: parentShape3
});

canvas.addShape(attacher);

// when
spaceTool.activateMakeSpace(canvasEvent({ x: 1200, y: 0 }));

dragging.move(canvasEvent({ x: 0, y: 0 }));

dragging.end();

// then
expect(parentShape3).to.have.bounds({
x: 1100,
y: 500,
width: 50,
height: 150
});
}
));

});

});


describe('minimum dimensions', function() {

it('should get minimum dimensions via event bus', inject(
Expand Down
Loading

0 comments on commit f1e760e

Please sign in to comment.