mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-19 04:57:51 +00:00
Get selected nodes
This commit is contained in:
parent
bfe6613871
commit
3d25633a38
@ -5,16 +5,30 @@ import {SVGSelection} from "../../../map/models/types";
|
||||
import {Node} from "../models/node.model";
|
||||
|
||||
|
||||
class OnSelectedListenerMock {
|
||||
public constructor(public nodes: Node[] = []) {}
|
||||
|
||||
public listen(nodes: Node[]) {
|
||||
console.log(this);
|
||||
this.nodes = nodes;
|
||||
}
|
||||
}
|
||||
|
||||
describe('SelectionTool', () => {
|
||||
let tool: SelectionTool;
|
||||
let svg: SVGSelection;
|
||||
let context: Context;
|
||||
let selection_line_tool: SVGSelection;
|
||||
let path_selection: SVGSelection;
|
||||
let selected_nodes: Node[];
|
||||
|
||||
beforeEach(() => {
|
||||
tool = new SelectionTool();
|
||||
|
||||
tool.selectedSubject.subscribe((nodes: Node[]) => {
|
||||
selected_nodes = nodes;
|
||||
});
|
||||
|
||||
svg = select('body')
|
||||
.append<SVGSVGElement>('svg')
|
||||
.attr('width', 1000)
|
||||
@ -95,14 +109,23 @@ describe('SelectionTool', () => {
|
||||
expect(svg.select('.selected').datum().name).toEqual("Node 1");
|
||||
});
|
||||
|
||||
it('selectedSubject should update nodes', () => {
|
||||
expect(selected_nodes.length).toEqual(1);
|
||||
});
|
||||
|
||||
describe('SelectionTool can deselect after click outside', () => {
|
||||
beforeEach(() => {
|
||||
svg.node().dispatchEvent(new MouseEvent('mousedown', {clientX: 300, clientY: 300}));
|
||||
window.dispatchEvent(new MouseEvent('mouseup', {clientX: 300, clientY: 300}));
|
||||
});
|
||||
|
||||
it('should have no selection', () => {
|
||||
expect(svg.selectAll('.selected').size()).toEqual(0);
|
||||
});
|
||||
|
||||
it('selectedSubject should clear nodes', () => {
|
||||
expect(selected_nodes.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -2,12 +2,20 @@ import {SVGSelection} from "../../../map/models/types";
|
||||
import {mouse, select} from "d3-selection";
|
||||
import {Context} from "../../../map/models/context";
|
||||
import {Node} from "../models/node.model";
|
||||
import {Subject} from "rxjs/Subject";
|
||||
|
||||
|
||||
export class SelectionTool {
|
||||
static readonly SELECTABLE_CLASS = '.selectable';
|
||||
|
||||
private selection: SVGSelection;
|
||||
private path;
|
||||
private context: Context;
|
||||
public selectedSubject: Subject<Node[]>;
|
||||
|
||||
public constructor() {
|
||||
this.selectedSubject = new Subject<Node[]>();
|
||||
}
|
||||
|
||||
public connect(selection: SVGSelection, context: Context) {
|
||||
this.selection = selection;
|
||||
@ -31,26 +39,17 @@ export class SelectionTool {
|
||||
self.startSelection(start);
|
||||
|
||||
// clear selection
|
||||
self.selection.selectAll('.selectable').classed("selected", false);
|
||||
self.selection
|
||||
.selectAll(SelectionTool.SELECTABLE_CLASS)
|
||||
.classed("selected", false);
|
||||
|
||||
subject
|
||||
.on("mousemove.selection", function() {
|
||||
const end = transformation(mouse(parent));
|
||||
self.moveSelection(start, end);
|
||||
|
||||
const x = Math.min(start[0], end[0]);
|
||||
const y = Math.min(start[1], end[1]);
|
||||
const width = Math.abs(start[0] - end[0]);
|
||||
const height = Math.abs(start[1] - end[1]);
|
||||
|
||||
self.selection
|
||||
.selectAll('.selectable')
|
||||
.classed('selected', (node: Node, i) => {
|
||||
return (x <= node.x && node.x < (x + width) && y <= node.y && node.y < (y + height));
|
||||
});
|
||||
|
||||
}).on("mouseup.selection", function() {
|
||||
self.endSelection(start, transformation(mouse(parent)));
|
||||
const end = transformation(mouse(parent));
|
||||
self.endSelection(start, end);
|
||||
subject
|
||||
.on("mousemove.selection", null)
|
||||
.on("mouseup.selection", null);
|
||||
@ -85,10 +84,33 @@ export class SelectionTool {
|
||||
|
||||
private moveSelection(start, move) {
|
||||
this.path.attr("d", this.rect(start[0], start[1], move[0] - start[0], move[1] - start[1]));
|
||||
this.getSelectedNodes(start, move);
|
||||
}
|
||||
|
||||
private endSelection(start, end) {
|
||||
this.path.attr("visibility", "hidden");
|
||||
const selected_nodes = this.getSelectedNodes(start, end);
|
||||
this.selectedSubject.next(selected_nodes);
|
||||
}
|
||||
|
||||
private getSelectedNodes(start, end): Node[] {
|
||||
const x = Math.min(start[0], end[0]);
|
||||
const y = Math.min(start[1], end[1]);
|
||||
const width = Math.abs(start[0] - end[0]);
|
||||
const height = Math.abs(start[1] - end[1]);
|
||||
const nodes: Node[] = [];
|
||||
|
||||
this.selection
|
||||
.selectAll(SelectionTool.SELECTABLE_CLASS)
|
||||
.classed('selected', (node: Node) => {
|
||||
const in_rect = (x <= node.x && node.x < (x + width) && y <= node.y && node.y < (y + height));
|
||||
if (in_rect) {
|
||||
nodes.push(node);
|
||||
}
|
||||
return in_rect;
|
||||
});
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private rect(x: number, y: number, w: number, h: number) {
|
||||
|
@ -47,6 +47,10 @@ svg image:hover, svg image.chosen, .selectable.selected {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
link.selectable.selected {
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.selection-line-tool .selection {
|
||||
fill: #7ccbe1;
|
||||
stroke: #66aec2 ;
|
||||
|
Loading…
Reference in New Issue
Block a user