mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-17 06:18:09 +00:00
Change the way of selection
This commit is contained in:
@ -15,17 +15,18 @@ describe('SelectionManager', () => {
|
|||||||
let nodesDataSource: NodesDataSource;
|
let nodesDataSource: NodesDataSource;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const linksDataSourec = new LinksDataSource();
|
const linksDataSource = new LinksDataSource();
|
||||||
const inRectangleHelper = new InRectangleHelper();
|
const inRectangleHelper = new InRectangleHelper();
|
||||||
|
|
||||||
selectedRectangleSubject = new Subject<Rectangle>();
|
selectedRectangleSubject = new Subject<Rectangle>();
|
||||||
|
|
||||||
nodesDataSource = new NodesDataSource();
|
nodesDataSource = new NodesDataSource();
|
||||||
|
|
||||||
manager = new SelectionManager(nodesDataSource, linksDataSourec, inRectangleHelper);
|
manager = new SelectionManager(nodesDataSource, linksDataSource, inRectangleHelper);
|
||||||
manager.subscribe(selectedRectangleSubject);
|
manager.subscribe(selectedRectangleSubject);
|
||||||
|
|
||||||
const node_1 = new Node();
|
const node_1 = new Node();
|
||||||
|
node_1.node_id = "test1";
|
||||||
node_1.name = "Node 1";
|
node_1.name = "Node 1";
|
||||||
node_1.x = 150;
|
node_1.x = 150;
|
||||||
node_1.y = 150;
|
node_1.y = 150;
|
||||||
@ -33,11 +34,15 @@ describe('SelectionManager', () => {
|
|||||||
nodesDataSource.add(node_1);
|
nodesDataSource.add(node_1);
|
||||||
|
|
||||||
const node_2 = new Node();
|
const node_2 = new Node();
|
||||||
|
node_2.node_id = "test2";
|
||||||
node_2.name = "Node 2";
|
node_2.name = "Node 2";
|
||||||
node_2.x = 300;
|
node_2.x = 300;
|
||||||
node_2.y = 300;
|
node_2.y = 300;
|
||||||
nodesDataSource.add(node_2);
|
nodesDataSource.add(node_2);
|
||||||
|
|
||||||
|
const link_1 = new Link();
|
||||||
|
link_1.link_id = "test1";
|
||||||
|
linksDataSource.add(link_1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('node should be selected', () => {
|
it('node should be selected', () => {
|
||||||
@ -56,12 +61,16 @@ describe('SelectionManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('nodes should be manually selected', () => {
|
it('nodes should be manually selected', () => {
|
||||||
manager.setSelectedNodes([new Node()]);
|
const node = new Node();
|
||||||
|
node.node_id = "test1";
|
||||||
|
manager.setSelectedNodes([node]);
|
||||||
expect(manager.getSelectedNodes().length).toEqual(1);
|
expect(manager.getSelectedNodes().length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('links should be manually selected', () => {
|
it('links should be manually selected', () => {
|
||||||
manager.setSelectedLinks([new Link()]);
|
const link = new Link();
|
||||||
|
link.link_id = "test1";
|
||||||
|
manager.setSelectedLinks([link]);
|
||||||
expect(manager.getSelectedLinks().length).toEqual(1);
|
expect(manager.getSelectedLinks().length).toEqual(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -45,25 +45,40 @@ export class SelectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedNodes(nodes: Node[]) {
|
public setSelectedNodes(nodes: Node[]) {
|
||||||
this.selectedNodes = nodes;
|
this.selectedNodes = this.setSelectedItems<Node>(this.nodesDataSource, (node: Node) => {
|
||||||
|
return !!nodes.find((n: Node) => node.node_id === n.node_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedLinks(links: Link[]) {
|
public setSelectedLinks(links: Link[]) {
|
||||||
this.selectedLinks = links;
|
this.selectedLinks = this.setSelectedItems<Link>(this.linksDataSource, (link: Link) => {
|
||||||
|
return !!links.find((l: Link) => link.link_id === l.link_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSelectedItemsInRectangle<T extends Selectable>(dataSource: DataSource<T>, rectangle: Rectangle) {
|
private getSelectedItemsInRectangle<T extends Selectable>(dataSource: DataSource<T>, rectangle: Rectangle) {
|
||||||
const items: T[] = [];
|
return this.setSelectedItems<T>(dataSource, (item: T) => {
|
||||||
dataSource.getItems().forEach((item: T) => {
|
return this.inRectangleHelper.inRectangle(item, rectangle);
|
||||||
const is_selected = this.inRectangleHelper.inRectangle(item, rectangle);
|
});
|
||||||
if (item.is_selected !== is_selected) {
|
|
||||||
item.is_selected = is_selected;
|
|
||||||
dataSource.update(item);
|
|
||||||
if (is_selected) {
|
|
||||||
items.push(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setSelected<T extends Selectable>(item: T, isSelected: boolean, dataSource: DataSource<T>): boolean {
|
||||||
|
if (item.is_selected !== isSelected) {
|
||||||
|
item.is_selected = isSelected;
|
||||||
|
dataSource.update(item);
|
||||||
|
}
|
||||||
|
return item.is_selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setSelectedItems<T extends Selectable>(dataSource: DataSource<T>, discriminator: (item: T) => boolean) {
|
||||||
|
const selected: T[] = [];
|
||||||
|
dataSource.getItems().forEach((item: T) => {
|
||||||
|
const isSelected = discriminator(item);
|
||||||
|
this.setSelected<T>(item, isSelected, dataSource);
|
||||||
|
if (isSelected) {
|
||||||
|
selected.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return items;
|
return selected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ export class EthernetLinkWidget implements Widget {
|
|||||||
const value_line = line();
|
const value_line = line();
|
||||||
|
|
||||||
let link_path = view.select<SVGPathElement>('path');
|
let link_path = view.select<SVGPathElement>('path');
|
||||||
link_path.classed('selectable', true);
|
|
||||||
link_path.classed('selected', (l: Link) => l.is_selected);
|
link_path.classed('selected', (l: Link) => l.is_selected);
|
||||||
|
|
||||||
if (!link_path.node()) {
|
if (!link_path.node()) {
|
||||||
|
@ -90,7 +90,7 @@ export class NodesWidget implements Widget {
|
|||||||
const node_enter = node
|
const node_enter = node
|
||||||
.enter()
|
.enter()
|
||||||
.append<SVGGElement>('g')
|
.append<SVGGElement>('g')
|
||||||
.attr('class', 'node selectable');
|
.attr('class', 'node');
|
||||||
|
|
||||||
node_enter
|
node_enter
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image')
|
||||||
|
@ -161,11 +161,15 @@ export class ProjectMapComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setUpMapCallbacks(project: Project) {
|
setUpMapCallbacks(project: Project) {
|
||||||
|
const selectionManager = new SelectionManager(this.nodesDataSource, this.linksDataSource, new InRectangleHelper());
|
||||||
|
|
||||||
this.mapChild.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any, node: Node) => {
|
this.mapChild.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any, node: Node) => {
|
||||||
this.nodeContextMenu.open(node, event.clientY, event.clientX);
|
this.nodeContextMenu.open(node, event.clientY, event.clientX);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.mapChild.graphLayout.getNodesWidget().setOnNodeClickedCallback((event: any, node: Node) => {
|
this.mapChild.graphLayout.getNodesWidget().setOnNodeClickedCallback((event: any, node: Node) => {
|
||||||
|
selectionManager.setSelectedNodes([node]);
|
||||||
|
|
||||||
if (this.drawLineMode) {
|
if (this.drawLineMode) {
|
||||||
this.nodeSelectInterfaceMenu.open(node, event.clientY, event.clientX);
|
this.nodeSelectInterfaceMenu.open(node, event.clientY, event.clientX);
|
||||||
}
|
}
|
||||||
@ -180,8 +184,6 @@ export class ProjectMapComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectionManager = new SelectionManager(this.nodesDataSource, this.linksDataSource, new InRectangleHelper());
|
|
||||||
|
|
||||||
selectionManager.subscribe(this.mapChild.graphLayout.getSelectionTool().rectangleSelected);
|
selectionManager.subscribe(this.mapChild.graphLayout.getSelectionTool().rectangleSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user