Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection selection outline + context pad position #826

Merged
merged 2 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions assets/diagram-js.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,13 @@
stroke: var(--element-selected-outline-stroke-color);
}

.djs-connection.selected .djs-outline {
display: none;
}

.djs-multi-select .djs-element.selected .djs-outline {
stroke: var(--element-selected-outline-secondary-stroke-color);
display: block;
}

.djs-shape.connect-ok .djs-visual > :nth-child(1) {
Expand Down
15 changes: 15 additions & 0 deletions lib/features/context-pad/ContextPad.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import {
escapeCSS
} from '../../util/EscapeUtil';

import { isConnection } from '../../util/ModelUtil';


/**
* @typedef {import('../../model/Types').Element} Element
*
Expand Down Expand Up @@ -507,12 +510,20 @@ ContextPad.prototype.isShown = function() {
/**
* Get contex pad position.
*
* If target is a connection, the context pad will be placed according to the
* connection's last waypoint.
*
* If multiple targets, the context pad will be placed according to the bounding
* box containing all targets.
*
* @param {ContextPadTarget} target
*
* @return {Rect}
*/
ContextPad.prototype._getPosition = function(target) {

target = isConnection(target) ? getLastWaypoint(target) : target;
barmac marked this conversation as resolved.
Show resolved Hide resolved

var elements = isArray(target) ? target : [ target ];
nikku marked this conversation as resolved.
Show resolved Hide resolved
var bBox = getBBox(elements);

Expand Down Expand Up @@ -545,4 +556,8 @@ function addClasses(element, classNames) {
*/
function includes(array, item) {
return array.indexOf(item) !== -1;
}

function getLastWaypoint(connection) {
return connection.waypoints[connection.waypoints.length - 1];
}
76 changes: 76 additions & 0 deletions test/spec/features/context-pad/ContextPadSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
classes as domClasses
} from 'min-dom';

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

import contextPadModule from 'lib/features/context-pad';
import selectionModule from 'lib/features/selection';

Expand Down Expand Up @@ -1356,4 +1358,78 @@ describe('features/context-pad', function() {
}));
});


describe('position', function() {

beforeEach(bootstrapDiagram({
modules: [
contextPadModule
]
}));


describe('single element', function() {

it('shape', inject(function(canvas, contextPad) {

// given
var shape = { id: 's1', width: 100, height: 100, x: 10, y: 10 };

canvas.addShape(shape);

// when
const pad = contextPad.getPad(shape);

// then
var bBox = getBBox(shape);
expect(pad.position).to.eql({
left: bBox.x + bBox.width + 12,
top: bBox.y - 12 / 2
});
}));


it('connection', inject(function(canvas, contextPad) {

// given
var connection = { id: 'c1', waypoints: [ { x: 0, y: 0 }, { x: 100, y: 100 } ] };

canvas.addConnection(connection);

// when
const pad = contextPad.getPad(connection);

// then
var bBox = getBBox(connection.waypoints[connection.waypoints.length - 1]);
expect(pad.position).to.eql({
left: bBox.x + bBox.width + 12,
top: bBox.y - 12 / 2
});
}));

});


it('multi element', inject(function(canvas, contextPad) {

// given
var shape1 = { id: 's1', width: 100, height: 100, x: 10, y: 10 };
var shape2 = { id: 's2', width: 100, height: 100, x: 210, y: 10 };

canvas.addShape(shape1);
canvas.addShape(shape2);

// when
const pad = contextPad.getPad([ shape1, shape2 ]);

// then
var bBox = getBBox([ shape1, shape2 ]);
expect(pad.position).to.eql({
left: bBox.x + bBox.width + 12,
top: bBox.y - 12 / 2
});
}));

});

});
24 changes: 24 additions & 0 deletions test/spec/features/selection/SelectionVisualsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@ describe('features/selection/SelectionVisuals', function() {
expect(domClasses(element).has('djs-multi-select'));
}));


it('should not show box for connection', inject(function(selection, canvas) {

// when
// debugger;
selection.select(connection);

// then
var gfx = canvas.getGraphics(connection),
outline = domQuery('.djs-outline', gfx);

expect(outline).to.exist;
expect(getComputedStyle(outline).display).to.equal('none');
}));

});


Expand Down Expand Up @@ -192,6 +207,15 @@ describe('features/selection/SelectionVisuals', function() {

}));


it('should show box for connection', inject(function(canvas) {
var gfx = canvas.getGraphics(connection),
outlineShape = domQuery('.djs-outline', gfx);

expect(outlineShape).to.exist;
expect(getComputedStyle(outlineShape).display).to.not.equal('none');
}));

});

});
Expand Down