diff --git a/src/app/app.module.ts b/src/app/app.module.ts index be596dd9..cd101275 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -186,6 +186,7 @@ import { DefaultConsoleService } from './services/settings/default-console.servi import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer'; import { NonNegativeValidator } from './validators/non-negative-validator'; import { RotationValidator } from './validators/rotation-validator'; +import { MapSettingService } from './services/mapsettings.service'; if (environment.production) { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { @@ -378,7 +379,8 @@ if (environment.production) { DefaultConsoleService, NodeCreatedLabelStylesFixer, NonNegativeValidator, - RotationValidator + RotationValidator, + MapSettingService ], entryComponents: [ AddServerDialogComponent, diff --git a/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts b/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts index 53193ad5..fb362b7e 100644 --- a/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts +++ b/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts @@ -21,6 +21,7 @@ import { MapLabel } from '../../models/map/map-label'; import { MapLinkNode } from '../../models/map/map-link-node'; import { select } from 'd3-selection'; import { MapLink } from '../../models/map/map-link'; +import { MapSettingService } from '../../../services/mapsettings.service'; describe('DraggableSelectionComponent', () => { let component: DraggableSelectionComponent; @@ -121,7 +122,8 @@ describe('DraggableSelectionComponent', () => { { provide: NodesEventSource, useValue: nodesEventSourceStub }, { provide: DrawingsEventSource, useValue: drawingsEventSourceStub }, { provide: GraphDataManager, useValue: mockedGraphDataManager }, - { provide: LinksEventSource, useValue: linksEventSourceStub } + { provide: LinksEventSource, useValue: linksEventSourceStub }, + { provide: MapSettingService, useClass: MapSettingService } ], declarations: [DraggableSelectionComponent] }).compileComponents(); diff --git a/src/app/cartography/components/draggable-selection/draggable-selection.component.ts b/src/app/cartography/components/draggable-selection/draggable-selection.component.ts index 37dce99b..5c284725 100644 --- a/src/app/cartography/components/draggable-selection/draggable-selection.component.ts +++ b/src/app/cartography/components/draggable-selection/draggable-selection.component.ts @@ -17,6 +17,7 @@ import { LabelWidget } from '../../widgets/label'; import { InterfaceLabelWidget } from '../../widgets/interface-label'; import { MapLinkNode } from '../../models/map/map-link-node'; import { LinksEventSource } from '../../events/links-event-source'; +import { MapSettingService } from '../../../services/mapsettings.service'; @Component({ selector: 'app-draggable-selection', @@ -27,6 +28,8 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { private start: Subscription; private drag: Subscription; private end: Subscription; + private mapSettingsSubscription: Subscription; + private isMapLocked: boolean = false; @Input('svg') svg: SVGSVGElement; @@ -40,12 +43,17 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { private nodesEventSource: NodesEventSource, private drawingsEventSource: DrawingsEventSource, private graphDataManager: GraphDataManager, - private linksEventSource: LinksEventSource + private linksEventSource: LinksEventSource, + private mapSettingsService: MapSettingService ) {} ngOnInit() { const svg = select(this.svg); + this.mapSettingsService.isMapLocked.subscribe((value) => { + this.isMapLocked = value; + }); + this.start = merge( this.nodesWidget.draggable.start, this.drawingsWidget.draggable.start, @@ -84,75 +92,77 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { this.labelWidget.draggable.drag, this.interfaceWidget.draggable.drag ).subscribe((evt: DraggableDrag) => { - const selected = this.selectionManager.getSelected(); - const selectedNodes = selected.filter(item => item instanceof MapNode); - // update nodes - selectedNodes.forEach((node: MapNode) => { - node.x += evt.dx; - node.y += evt.dy; + if (!this.isMapLocked) { + const selected = this.selectionManager.getSelected(); + const selectedNodes = selected.filter(item => item instanceof MapNode); + // update nodes + selectedNodes.forEach((node: MapNode) => { + node.x += evt.dx; + node.y += evt.dy; - this.nodesWidget.redrawNode(svg, node); + this.nodesWidget.redrawNode(svg, node); - const links = this.graphDataManager - .getLinks() - .filter( - link => - (link.target !== undefined && link.target.id === node.id) || - (link.source !== undefined && 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); - }); - - // update labels - selected - .filter(item => item instanceof MapLabel) - .forEach((label: MapLabel) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; - if (isParentNodeSelected) { - return; - } - - const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0]; - node.label.x += evt.dx; - node.label.y += evt.dy; - this.labelWidget.redrawLabel(svg, label); - }); - - // update interface labels - selected - .filter(item => item instanceof MapLinkNode) - .forEach((interfaceLabel: MapLinkNode) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0; - if (isParentNodeSelected) { - return; - } - - const link = this.graphDataManager + const links = this.graphDataManager .getLinks() - .filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0]; - if (link.nodes[0].id === interfaceLabel.id) { - link.nodes[0].label.x += evt.dx; - link.nodes[0].label.y += evt.dy; - } - if (link.nodes[1].id === interfaceLabel.id) { - link.nodes[1].label.x += evt.dx; - link.nodes[1].label.y += evt.dy; - } + .filter( + link => + (link.target !== undefined && link.target.id === node.id) || + (link.source !== undefined && link.source.id === node.id) + ); - this.linksWidget.redrawLink(svg, link); + 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); + }); + + // update labels + selected + .filter(item => item instanceof MapLabel) + .forEach((label: MapLabel) => { + const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + if (isParentNodeSelected) { + return; + } + + const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0]; + node.label.x += evt.dx; + node.label.y += evt.dy; + this.labelWidget.redrawLabel(svg, label); + }); + + // update interface labels + selected + .filter(item => item instanceof MapLinkNode) + .forEach((interfaceLabel: MapLinkNode) => { + const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0; + if (isParentNodeSelected) { + return; + } + + const link = this.graphDataManager + .getLinks() + .filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0]; + if (link.nodes[0].id === interfaceLabel.id) { + link.nodes[0].label.x += evt.dx; + link.nodes[0].label.y += evt.dy; + } + if (link.nodes[1].id === interfaceLabel.id) { + link.nodes[1].label.x += evt.dx; + link.nodes[1].label.y += evt.dy; + } + + this.linksWidget.redrawLink(svg, link); + }); + } }); this.end = merge( @@ -161,39 +171,41 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { this.labelWidget.draggable.end, this.interfaceWidget.draggable.end ).subscribe((evt: DraggableEnd) => { - const selected = this.selectionManager.getSelected(); - const selectedNodes = selected.filter(item => item instanceof MapNode); + if (!this.isMapLocked) { + const selected = this.selectionManager.getSelected(); + const selectedNodes = selected.filter(item => item instanceof MapNode); - selectedNodes.forEach((item: MapNode) => { - this.nodesEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); - }); - - selected - .filter(item => item instanceof MapDrawing) - .forEach((item: MapDrawing) => { - this.drawingsEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); + selectedNodes.forEach((item: MapNode) => { + this.nodesEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); }); - selected - .filter(item => item instanceof MapLabel) - .forEach((label: MapLabel) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; - if (isParentNodeSelected) { - return; - } + selected + .filter(item => item instanceof MapDrawing) + .forEach((item: MapDrawing) => { + this.drawingsEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); + }); - this.nodesEventSource.labelDragged.emit(new DraggedDataEvent(label, evt.dx, evt.dy)); - }); + selected + .filter(item => item instanceof MapLabel) + .forEach((label: MapLabel) => { + const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + if (isParentNodeSelected) { + return; + } - selected - .filter(item => item instanceof MapLinkNode) - .forEach((label: MapLinkNode) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; - if (isParentNodeSelected) { - return; - } - this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent(label, evt.dx, evt.dy)); - }); + this.nodesEventSource.labelDragged.emit(new DraggedDataEvent(label, evt.dx, evt.dy)); + }); + + selected + .filter(item => item instanceof MapLinkNode) + .forEach((label: MapLinkNode) => { + const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + if (isParentNodeSelected) { + return; + } + this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent(label, evt.dx, evt.dy)); + }); + } }); } @@ -201,5 +213,6 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { this.start.unsubscribe(); this.drag.unsubscribe(); this.end.unsubscribe(); + this.mapSettingsSubscription.unsubscribe(); } } diff --git a/src/app/components/project-map/project-map.component.spec.ts b/src/app/components/project-map/project-map.component.spec.ts index bd399179..a8898837 100644 --- a/src/app/components/project-map/project-map.component.spec.ts +++ b/src/app/components/project-map/project-map.component.spec.ts @@ -43,6 +43,7 @@ import { Project } from '../../models/project'; import { CapturingSettings } from '../../models/capturingSettings'; import { LinkWidget } from '../../cartography/widgets/link'; import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer'; +import { MapSettingService } from '../../services/mapsettings.service'; export class MockedProgressService { public activate() {} @@ -220,7 +221,8 @@ describe('ProjectMapComponent', () => { provide: RecentlyOpenedProjectService, useClass: RecentlyOpenedProjectService }, - { provide: NodeCreatedLabelStylesFixer, useValue: nodeCreatedLabelStylesFixer} + { provide: NodeCreatedLabelStylesFixer, useValue: nodeCreatedLabelStylesFixer}, + { provide: MapSettingService } ], declarations: [ProjectMapComponent, D3MapComponent, ...ANGULAR_MAP_DECLARATIONS], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index cbc87083..c9a84372 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -44,7 +44,7 @@ import { MapLink } from '../../cartography/models/map/map-link'; import { MapLinkToLinkConverter } from '../../cartography/converters/map/map-link-to-link-converter'; import { LinkWidget } from '../../cartography/widgets/link'; import { NodeCreatedLabelStylesFixer } from './helpers/node-created-label-styles-fixer'; -import { MovingTool } from '../../cartography/tools/moving-tool'; +import { MapSettingService } from '../../services/mapsettings.service'; @Component({ @@ -111,9 +111,9 @@ export class ProjectMapComponent implements OnInit, OnDestroy { private toolsService: ToolsService, private selectionManager: SelectionManager, private selectionTool: SelectionTool, - private movingTool: MovingTool, private recentlyOpenedProjectService: RecentlyOpenedProjectService, - private nodeCreatedLabelStylesFixer: NodeCreatedLabelStylesFixer + private nodeCreatedLabelStylesFixer: NodeCreatedLabelStylesFixer, + private mapSettingsService: MapSettingService ) {} ngOnInit() { @@ -400,7 +400,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { public changeLockValue() { this.isLocked = !this.isLocked; - this.movingTool.setEnabled(this.isLocked); + this.mapSettingsService.changeMapLockValue(this.isLocked); } public ngOnDestroy() { diff --git a/src/app/services/mapsettings.service.ts b/src/app/services/mapsettings.service.ts new file mode 100644 index 00000000..640c5671 --- /dev/null +++ b/src/app/services/mapsettings.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from "@angular/core"; +import { Subject } from 'rxjs'; + +@Injectable() +export class MapSettingService { + public isMapLocked = new Subject(); + + constructor() {} + + changeMapLockValue(value: boolean) { + this.isMapLocked.next(value); + } +}