Skip to content

Commit d20f509

Browse files
refactor: move multi selection outline into separate feature
closes to #944
1 parent 65bd338 commit d20f509

File tree

8 files changed

+399
-257
lines changed

8 files changed

+399
-257
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import {
2+
append as svgAppend,
3+
attr as svgAttr,
4+
create as svgCreate,
5+
classes as svgClasses,
6+
clear as svgClear
7+
} from 'tiny-svg';
8+
9+
import { assign } from 'min-dash';
10+
11+
import { getBBox } from '../../util/Elements';
12+
13+
var SELECTION_OUTLINE_PADDING = 6;
14+
15+
/**
16+
* @typedef {import('../../model/Types').Element} Element
17+
*
18+
* @typedef {import('../../core/EventBus').default} EventBus
19+
* @typedef {import('../selection/Selection').default} Selection
20+
* @typedef {import('../../core/Canvas').default} Canvas
21+
*/
22+
23+
/**
24+
* @class
25+
*
26+
* A plugin that adds an outline to shapes and connections that may be activated and styled
27+
* via CSS classes.
28+
*
29+
* @param {EventBus} eventBus
30+
* @param {Canvas} canvas
31+
* @param {Selection} selection
32+
*/
33+
export default function MultiSelectionOutline(eventBus, canvas, selection) {
34+
this._canvas = canvas;
35+
36+
var self = this;
37+
38+
eventBus.on('element.changed', function(event) {
39+
if (selection.isSelected(event.element)) {
40+
self._updateMultiSelectionOutline(selection.get());
41+
}
42+
});
43+
44+
eventBus.on('selection.changed', function(event) {
45+
var newSelection = event.newSelection;
46+
47+
self._updateMultiSelectionOutline(newSelection);
48+
});
49+
}
50+
51+
52+
53+
MultiSelectionOutline.prototype._updateMultiSelectionOutline = function(selection) {
54+
var layer = this._canvas.getLayer('selectionOutline');
55+
56+
svgClear(layer);
57+
58+
var enabled = selection.length > 1;
59+
60+
var container = this._canvas.getContainer();
61+
62+
svgClasses(container)[enabled ? 'add' : 'remove']('djs-multi-select');
63+
64+
if (!enabled) {
65+
return;
66+
}
67+
68+
var bBox = addSelectionOutlinePadding(getBBox(selection));
69+
70+
var rect = svgCreate('rect');
71+
72+
svgAttr(rect, assign({
73+
rx: 3
74+
}, bBox));
75+
76+
svgClasses(rect).add('djs-selection-outline');
77+
78+
svgAppend(layer, rect);
79+
};
80+
81+
82+
MultiSelectionOutline.$inject = [ 'eventBus', 'canvas', 'selection' ];
83+
84+
// helpers //////////
85+
86+
function addSelectionOutlinePadding(bBox) {
87+
return {
88+
x: bBox.x - SELECTION_OUTLINE_PADDING,
89+
y: bBox.y - SELECTION_OUTLINE_PADDING,
90+
width: bBox.width + SELECTION_OUTLINE_PADDING * 2,
91+
height: bBox.height + SELECTION_OUTLINE_PADDING * 2
92+
};
93+
}

lib/features/outline/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
import SelectionModule from '../selection';
2+
13
import Outline from './Outline';
4+
import MultiSelectionOutline from './MultiSelectionOutline';
25

36

47
/**
58
* @type { import('didi').ModuleDeclaration }
69
*/
710
export default {
8-
__init__: [ 'outline' ],
9-
outline: [ 'type', Outline ]
11+
__depends__: [
12+
SelectionModule
13+
],
14+
__init__: [ 'outline', 'multiSelectionOutline' ],
15+
outline: [ 'type', Outline ],
16+
multiSelectionOutline: [ 'type', MultiSelectionOutline ]
1017
};
Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,15 @@
11
import {
2-
assign,
32
forEach
43
} from 'min-dash';
54

6-
import {
7-
append as svgAppend,
8-
attr as svgAttr,
9-
classes as svgClasses,
10-
clear as svgClear,
11-
create as svgCreate
12-
} from 'tiny-svg';
13-
14-
import { getBBox } from '../../util/Elements';
15-
165
/**
176
* @typedef {import('../../core/Canvas').default} Canvas
187
* @typedef {import('../../core/EventBus').default} EventBus
19-
* @typedef {import('./Selection').default} Selection
208
*/
219

2210
var MARKER_HOVER = 'hover',
2311
MARKER_SELECTED = 'selected';
2412

25-
var SELECTION_OUTLINE_PADDING = 6;
26-
27-
2813
/**
2914
* A plugin that adds a visible selection UI to shapes and connections
3015
* by appending the <code>hover</code> and <code>selected</code> classes to them.
@@ -35,15 +20,10 @@ var SELECTION_OUTLINE_PADDING = 6;
3520
*
3621
* @param {Canvas} canvas
3722
* @param {EventBus} eventBus
38-
* @param {Selection} selection
3923
*/
40-
export default function SelectionVisuals(canvas, eventBus, selection) {
24+
export default function SelectionVisuals(canvas, eventBus) {
4125
this._canvas = canvas;
4226

43-
var self = this;
44-
45-
this._multiSelectionBox = null;
46-
4727
function addMarker(e, cls) {
4828
canvas.addMarker(e, cls);
4929
}
@@ -84,59 +64,10 @@ export default function SelectionVisuals(canvas, eventBus, selection) {
8464
select(e);
8565
}
8666
});
87-
88-
self._updateSelectionOutline(newSelection);
89-
});
90-
91-
92-
eventBus.on('element.changed', function(event) {
93-
if (selection.isSelected(event.element)) {
94-
self._updateSelectionOutline(selection.get());
95-
}
9667
});
9768
}
9869

9970
SelectionVisuals.$inject = [
10071
'canvas',
101-
'eventBus',
102-
'selection'
72+
'eventBus'
10373
];
104-
105-
SelectionVisuals.prototype._updateSelectionOutline = function(selection) {
106-
var layer = this._canvas.getLayer('selectionOutline');
107-
108-
svgClear(layer);
109-
110-
var enabled = selection.length > 1;
111-
112-
var container = this._canvas.getContainer();
113-
114-
svgClasses(container)[enabled ? 'add' : 'remove']('djs-multi-select');
115-
116-
if (!enabled) {
117-
return;
118-
}
119-
120-
var bBox = addSelectionOutlinePadding(getBBox(selection));
121-
122-
var rect = svgCreate('rect');
123-
124-
svgAttr(rect, assign({
125-
rx: 3
126-
}, bBox));
127-
128-
svgClasses(rect).add('djs-selection-outline');
129-
130-
svgAppend(layer, rect);
131-
};
132-
133-
// helpers //////////
134-
135-
function addSelectionOutlinePadding(bBox) {
136-
return {
137-
x: bBox.x - SELECTION_OUTLINE_PADDING,
138-
y: bBox.y - SELECTION_OUTLINE_PADDING,
139-
width: bBox.width + SELECTION_OUTLINE_PADDING * 2,
140-
height: bBox.height + SELECTION_OUTLINE_PADDING * 2
141-
};
142-
}

lib/features/selection/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import InteractionEventsModule from '../interaction-events';
2-
import OutlineModule from '../outline';
32

43
import Selection from './Selection';
54
import SelectionVisuals from './SelectionVisuals';
@@ -13,7 +12,6 @@ export default {
1312
__init__: [ 'selectionVisuals', 'selectionBehavior' ],
1413
__depends__: [
1514
InteractionEventsModule,
16-
OutlineModule
1715
],
1816
selection: [ 'type', Selection ],
1917
selectionVisuals: [ 'type', SelectionVisuals ],

0 commit comments

Comments
 (0)