mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-17 06:18:09 +00:00
Missing files
This commit is contained in:
9
src/app/cartography/events/selection-event-source.ts
Normal file
9
src/app/cartography/events/selection-event-source.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Subject } from "rxjs";
|
||||||
|
import { Rectangle } from "../models/rectangle";
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SelectionEventSource {
|
||||||
|
public selected = new Subject<Rectangle>();
|
||||||
|
}
|
@ -1,105 +0,0 @@
|
|||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { NodesWidget } from "../widgets/nodes";
|
|
||||||
import { DraggableStart, DraggableDrag, DraggableEnd } from "../events/draggable";
|
|
||||||
import { Subscription } from "rxjs";
|
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
|
||||||
import { LinksWidget } from "../widgets/links";
|
|
||||||
import { NodesEventSource } from "../events/nodes-event-source";
|
|
||||||
import { DraggedDataEvent } from "../events/event-source";
|
|
||||||
import { MapNode } from "../models/map/map-node";
|
|
||||||
import { GraphDataManager } from "../managers/graph-data-manager";
|
|
||||||
import { DrawingsWidget } from "../widgets/drawings";
|
|
||||||
import { merge } from "rxjs";
|
|
||||||
import { MapDrawing } from "../models/map/map-drawing";
|
|
||||||
import { DrawingsEventSource } from "../events/drawings-event-source";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class DraggableListener {
|
|
||||||
private start: Subscription;
|
|
||||||
private drag: Subscription;
|
|
||||||
private end: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private nodesWidget: NodesWidget,
|
|
||||||
private drawingsWidget: DrawingsWidget,
|
|
||||||
private linksWidget: LinksWidget,
|
|
||||||
private selectionManager: SelectionManager,
|
|
||||||
private nodesEventSource: NodesEventSource,
|
|
||||||
private drawingsEventSource: DrawingsEventSource,
|
|
||||||
private graphDataManager: GraphDataManager
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public onInit(svg: any) {
|
|
||||||
this.start = merge(
|
|
||||||
this.nodesWidget.draggable.start,
|
|
||||||
this.drawingsWidget.draggable.start
|
|
||||||
).subscribe((evt: DraggableStart<any>) => {
|
|
||||||
const selected = this.selectionManager.getSelected();
|
|
||||||
|
|
||||||
if (evt.datum instanceof MapNode) {
|
|
||||||
if (selected.filter((item) => item instanceof MapNode && item.id === evt.datum.id).length === 0) {
|
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evt.datum instanceof MapDrawing) {
|
|
||||||
if (selected.filter((item) => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) {
|
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.drag = merge(
|
|
||||||
this.nodesWidget.draggable.drag,
|
|
||||||
this.drawingsWidget.draggable.drag
|
|
||||||
).subscribe((evt: DraggableDrag<any>) => {
|
|
||||||
const selected = this.selectionManager.getSelected();
|
|
||||||
|
|
||||||
// update nodes
|
|
||||||
selected.filter((item) => item instanceof MapNode).forEach((node: MapNode) => {
|
|
||||||
node.x += evt.dx;
|
|
||||||
node.y += evt.dy;
|
|
||||||
|
|
||||||
this.nodesWidget.redrawNode(svg, node);
|
|
||||||
|
|
||||||
const links = this.graphDataManager.getLinks().filter(
|
|
||||||
(link) => link.target.id === node.id || link.source.id === node.id);
|
|
||||||
links.forEach((link) => {
|
|
||||||
this.linksWidget.redrawLink(svg, link);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// update drawings
|
|
||||||
selected.filter((item) => item instanceof MapDrawing).forEach((drawing: MapDrawing) => {
|
|
||||||
drawing.x += evt.dx;
|
|
||||||
drawing.y += evt.dy;
|
|
||||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
this.end = merge(
|
|
||||||
this.nodesWidget.draggable.end,
|
|
||||||
this.drawingsWidget.draggable.end
|
|
||||||
).subscribe((evt: DraggableEnd<any>) => {
|
|
||||||
const selected = this.selectionManager.getSelected();
|
|
||||||
|
|
||||||
selected.filter((item) => item instanceof MapNode).forEach((item: MapNode) => {
|
|
||||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(item, evt.dx, evt.dy));
|
|
||||||
})
|
|
||||||
|
|
||||||
selected.filter((item) => item instanceof MapDrawing).forEach((item: MapDrawing) => {
|
|
||||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public onDestroy() {
|
|
||||||
this.start.unsubscribe();
|
|
||||||
this.drag.unsubscribe();
|
|
||||||
this.end.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
export interface MapListener {
|
|
||||||
onInit(svg: any);
|
|
||||||
onDestroy();
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { MapListener } from "./map-listener";
|
|
||||||
import { DraggableListener } from "./draggable-listener";
|
|
||||||
import { SelectionUpdateListener } from "./selection-update-listener";
|
|
||||||
import { SelectionListener } from "./selection-listener";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class MapListeners {
|
|
||||||
private listeners: MapListener[] = [];
|
|
||||||
constructor(
|
|
||||||
private nodesDraggableListener: DraggableListener,
|
|
||||||
private selectionUpdateListener: SelectionUpdateListener,
|
|
||||||
private selectionListener: SelectionListener
|
|
||||||
) {
|
|
||||||
this.listeners.push(this.nodesDraggableListener);
|
|
||||||
this.listeners.push(this.selectionUpdateListener);
|
|
||||||
this.listeners.push(this.selectionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public onInit(svg: any) {
|
|
||||||
this.listeners.forEach((listener) => {
|
|
||||||
listener.onInit(svg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onDestroy() {
|
|
||||||
this.listeners.forEach((listener) => {
|
|
||||||
listener.onDestroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
import { Rectangle } from "../models/rectangle";
|
|
||||||
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
|
||||||
import { MapNode } from "../models/map/map-node";
|
|
||||||
import { MapLink } from "../models/map/map-link";
|
|
||||||
import { mock, instance, when } from "ts-mockito";
|
|
||||||
import { fakeAsync, tick } from "@angular/core/testing";
|
|
||||||
import { SelectionListener } from "./selection-listener";
|
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
|
||||||
import { GraphDataManager } from "../managers/graph-data-manager";
|
|
||||||
import { SelectionTool } from "../tools/selection-tool";
|
|
||||||
import { Context } from "../models/context";
|
|
||||||
|
|
||||||
|
|
||||||
describe('SelectionListener', () => {
|
|
||||||
let selectionListener: SelectionListener;
|
|
||||||
let manager: SelectionManager;
|
|
||||||
let selectionTool: SelectionTool;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
const mockedGraphData = mock(GraphDataManager);
|
|
||||||
|
|
||||||
const node_1 = new MapNode();
|
|
||||||
node_1.id = "test1";
|
|
||||||
node_1.name = "Node 1";
|
|
||||||
node_1.x = 150;
|
|
||||||
node_1.y = 150;
|
|
||||||
|
|
||||||
const node_2 = new MapNode();
|
|
||||||
node_2.id = "test2";
|
|
||||||
node_2.name = "Node 2";
|
|
||||||
node_2.x = 300;
|
|
||||||
node_2.y = 300;
|
|
||||||
|
|
||||||
const link_1 = new MapLink();
|
|
||||||
link_1.id = "test1";
|
|
||||||
|
|
||||||
when(mockedGraphData.getNodes()).thenReturn([node_1, node_2]);
|
|
||||||
when(mockedGraphData.getLinks()).thenReturn([link_1]);
|
|
||||||
when(mockedGraphData.getDrawings()).thenReturn([]);
|
|
||||||
|
|
||||||
const graphData = instance(mockedGraphData);
|
|
||||||
const inRectangleHelper = new InRectangleHelper();
|
|
||||||
|
|
||||||
manager = new SelectionManager();
|
|
||||||
selectionTool = new SelectionTool(new Context());
|
|
||||||
selectionListener = new SelectionListener(selectionTool, graphData, inRectangleHelper, manager);
|
|
||||||
selectionListener.onInit(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
selectionListener.onDestroy();
|
|
||||||
})
|
|
||||||
|
|
||||||
it('node should be selected', fakeAsync(() => {
|
|
||||||
selectionTool.rectangleSelected.next(new Rectangle(100, 100, 100, 100));
|
|
||||||
tick();
|
|
||||||
expect(manager.getSelected().length).toEqual(1);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('node should be selected and deselected', fakeAsync(() => {
|
|
||||||
selectionTool.rectangleSelected.next(new Rectangle(100, 100, 100, 100));
|
|
||||||
tick();
|
|
||||||
selectionTool.rectangleSelected.next(new Rectangle(350, 350, 100, 100));
|
|
||||||
tick();
|
|
||||||
expect(manager.getSelected().length).toEqual(0);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
@ -1,45 +0,0 @@
|
|||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { GraphDataManager } from "../managers/graph-data-manager";
|
|
||||||
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
|
||||||
import { SelectionTool } from "../tools/selection-tool";
|
|
||||||
import { Subscription } from "rxjs";
|
|
||||||
import { Rectangle } from "electron";
|
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SelectionListener {
|
|
||||||
private onSelection: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private selectionTool: SelectionTool,
|
|
||||||
private graphDataManager: GraphDataManager,
|
|
||||||
private inRectangleHelper: InRectangleHelper,
|
|
||||||
private selectionManager: SelectionManager
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public onInit(svg: any) {
|
|
||||||
this.onSelection = this.selectionTool.rectangleSelected.subscribe((rectangle: Rectangle) => {
|
|
||||||
const selectedNodes = this.graphDataManager.getNodes().filter((node) => {
|
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y)
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y)
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => {
|
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y)
|
|
||||||
});
|
|
||||||
|
|
||||||
const selected = [...selectedNodes, ...selectedLinks, ...selectedDrawings];
|
|
||||||
|
|
||||||
this.selectionManager.setSelected(selected);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onDestroy() {
|
|
||||||
this.onSelection.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { Subscription } from "rxjs";
|
|
||||||
import { MapChangeDetectorRef } from "../services/map-change-detector-ref";
|
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SelectionUpdateListener {
|
|
||||||
private onSelected: Subscription;
|
|
||||||
private onUnselected: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private selectionManager: SelectionManager,
|
|
||||||
private mapChangeDetectorRef: MapChangeDetectorRef
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public onInit(svg: any) {
|
|
||||||
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
|
||||||
});
|
|
||||||
this.onUnselected = this.selectionManager.unselected.subscribe(() => {
|
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onDestroy() {
|
|
||||||
this.onSelected.unsubscribe();
|
|
||||||
this.onUnselected.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user