From b57bc7370b8dd538a9bfcf2df8e693b70a5e8c14 Mon Sep 17 00:00:00 2001 From: ziajka Date: Wed, 7 Nov 2018 14:44:17 +0100 Subject: [PATCH] New approach for draggable --- src/app/cartography/cartography.module.ts | 2 + .../components/map/map.component.ts | 8 ++- src/app/cartography/events/draggable.ts | 64 +++++++++++++++++++ src/app/cartography/listeners/map-listener.ts | 47 ++++++++++++++ src/app/cartography/widgets/drawings.ts | 13 +++- .../project-map/project-map.component.html | 1 - .../project-map/project-map.component.ts | 38 +++++------ 7 files changed, 147 insertions(+), 26 deletions(-) create mode 100644 src/app/cartography/events/draggable.ts create mode 100644 src/app/cartography/listeners/map-listener.ts diff --git a/src/app/cartography/cartography.module.ts b/src/app/cartography/cartography.module.ts index c276d253..0161de52 100644 --- a/src/app/cartography/cartography.module.ts +++ b/src/app/cartography/cartography.module.ts @@ -16,6 +16,7 @@ import { MapChangeDetectorRef } from './services/map-change-detector-ref'; import { Context } from './models/context'; import { D3_MAP_IMPORTS } from './d3-map.imports'; import { CanvasSizeDetector } from './helpers/canvas-size-detector'; +import { MapListener } from './listeners/map-listener'; @NgModule({ @@ -39,6 +40,7 @@ import { CanvasSizeDetector } from './helpers/canvas-size-detector'; MapChangeDetectorRef, CanvasSizeDetector, Context, + MapListener, ...D3_MAP_IMPORTS ], exports: [ MapComponent ] diff --git a/src/app/cartography/components/map/map.component.ts b/src/app/cartography/components/map/map.component.ts index fe50656d..e120afcb 100644 --- a/src/app/cartography/components/map/map.component.ts +++ b/src/app/cartography/components/map/map.component.ts @@ -22,6 +22,7 @@ import { LinkCreated } from '../../events/links'; import { CanvasSizeDetector } from '../../helpers/canvas-size-detector'; import { SelectionManager } from '../../managers/selection-manager'; import { NodeWidget } from '../../widgets/node'; +import { MapListener } from '../../listeners/map-listener'; @Component({ @@ -35,8 +36,6 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { @Input() drawings: Drawing[] = []; @Input() symbols: Symbol[] = []; - @Input('selection-manager') selectionManager: SelectionManager; - @Input() width = 1500; @Input() height = 600; @@ -60,6 +59,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { private context: Context, private mapChangeDetectorRef: MapChangeDetectorRef, private canvasSizeDetector: CanvasSizeDetector, + private mapListener: MapListener, + private selectionManager: SelectionManager, protected element: ElementRef, protected nodesWidget: NodesWidget, protected nodeWidget: NodeWidget, @@ -123,6 +124,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { this.onNodeClickedSubscription.unsubscribe(); this.onNodeDraggedSubscription.unsubscribe(); this.onChangesDetected.unsubscribe(); + this.mapListener.onDestroy(); } ngOnInit() { @@ -175,6 +177,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { this.reload(); } }); + + this.mapListener.onInit(this.svg); } public createGraph(domElement: HTMLElement) { diff --git a/src/app/cartography/events/draggable.ts b/src/app/cartography/events/draggable.ts new file mode 100644 index 00000000..3cefb1ee --- /dev/null +++ b/src/app/cartography/events/draggable.ts @@ -0,0 +1,64 @@ +import { EventEmitter } from "@angular/core"; +import { drag, DraggedElementBaseType } from "d3-drag"; +import { event } from "d3-selection"; + +class DraggableEvent { + public dx: number; + public dy: number; +} + +export class DraggableStart extends DraggableEvent { + constructor( + public datum: T + ){ + super(); + } +} + +export class DraggableDrag extends DraggableEvent { + constructor( + public datum: T + ){ + super(); + } +} + +export class DraggableEnd extends DraggableEvent { + constructor( + public datum: T + ){ + super(); + } +} + +export class Draggable { + public start = new EventEmitter>(); + public drag = new EventEmitter>(); + public end = new EventEmitter>(); + + public call(selection) { + selection.call(this.behaviour()); + } + + private behaviour() { + return drag() + .on('start', (datum: Datum) => { + const evt = new DraggableStart(datum); + evt.dx = event.dx; + evt.dy = event.dy; + this.start.emit(evt); + }) + .on('drag', (datum: Datum) => { + const evt = new DraggableDrag(datum); + evt.dx = event.dx; + evt.dy = event.dy; + this.drag.emit(evt); + }) + .on('end', (datum: Datum) => { + const evt = new DraggableEnd(datum); + evt.dx = event.dx; + evt.dy = event.dy; + this.end.emit(evt); + }); + } +} \ No newline at end of file diff --git a/src/app/cartography/listeners/map-listener.ts b/src/app/cartography/listeners/map-listener.ts new file mode 100644 index 00000000..b6dd2aad --- /dev/null +++ b/src/app/cartography/listeners/map-listener.ts @@ -0,0 +1,47 @@ +import { Injectable } from "@angular/core"; +import { DrawingsWidget } from "../widgets/drawings"; +import { DraggableStart } from "../events/draggable"; +import { Drawing } from "../models/drawing"; +import { Subscription } from "rxjs"; +import { SelectionManager } from "../managers/selection-manager"; + + +@Injectable() +export class MapListener { + private start: Subscription; + private drag: Subscription; + private end: Subscription; + + constructor( + private drawingsWidget: DrawingsWidget, + private selectionManager: SelectionManager + ) { + } + + public onInit(svg: any) { + this.start = this.drawingsWidget.draggable.start.subscribe((evt: DraggableStart) => { + let drawings = this.selectionManager.getSelectedDrawings(); + + if (drawings.filter((n: Drawing) => n.drawing_id === evt.datum.drawing_id).length === 0) { + this.selectionManager.setSelectedDrawings([evt.datum]); + drawings = this.selectionManager.getSelectedDrawings(); + } + }); + + this.drag = this.drawingsWidget.draggable.start.subscribe((evt: DraggableStart) => { + let drawings = this.selectionManager.getSelectedDrawings(); + drawings.forEach((drawing: Drawing) => { + drawing.x += evt.dx; + drawing.y += evt.dy; + // this.drawingsWidget.redrawDrawing(svg, drawing); + }); + }); + + } + + public onDestroy() { + this.start.unsubscribe(); + this.drag.unsubscribe(); + this.end.unsubscribe(); + } +} \ No newline at end of file diff --git a/src/app/cartography/widgets/drawings.ts b/src/app/cartography/widgets/drawings.ts index 7f08d6ee..a70aa955 100644 --- a/src/app/cartography/widgets/drawings.ts +++ b/src/app/cartography/widgets/drawings.ts @@ -1,4 +1,4 @@ -import { Injectable } from "@angular/core"; +import { Injectable, EventEmitter } from "@angular/core"; import { Widget } from "./widget"; import { Drawing } from "../models/drawing"; @@ -11,12 +11,22 @@ import { RectDrawingWidget } from "./drawings/rect-drawing"; import { LineDrawingWidget } from "./drawings/line-drawing"; import { EllipseDrawingWidget } from "./drawings/ellipse-drawing"; import { DrawingWidget } from "./drawings/drawing-widget"; +import { event } from "d3-selection"; +import { D3DragEvent, drag } from "d3-drag"; +import { Draggable } from "../events/draggable"; @Injectable() export class DrawingsWidget implements Widget { private drawingWidgets: DrawingWidget[] = []; + public draggable = new Draggable(); + + // public onContextMenu = new EventEmitter(); + // public onDrawingClicked = new EventEmitter(); + // public onDrawingDragged = new EventEmitter(); + // public onDrawingDragging = new EventEmitter(); + constructor( private svgToDrawingConverter: SvgToDrawingConverter, private textDrawingWidget: TextDrawingWidget, @@ -69,5 +79,6 @@ export class DrawingsWidget implements Widget { .exit() .remove(); + this.draggable.call(drawing_merge); } } diff --git a/src/app/components/project-map/project-map.component.html b/src/app/components/project-map/project-map.component.html index aba18853..806473b6 100644 --- a/src/app/components/project-map/project-map.component.html +++ b/src/app/components/project-map/project-map.component.html @@ -6,7 +6,6 @@ [drawings]="drawings" [width]="project.scene_width" [height]="project.scene_height" - [selection-manager]="selectionManager" [show-interface-labels]="project.show_interface_labels" [selection-tool]="tools.selection" [moving-tool]="tools.moving" diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index b8bf7f25..b262ad92 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -57,34 +57,28 @@ export class ProjectMapComponent implements OnInit, OnDestroy { private inReadOnlyMode = false; - protected selectionManager: SelectionManager; - @ViewChild(MapComponent) mapChild: MapComponent; @ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent; - private subscriptions: Subscription[]; + private subscriptions: Subscription[] = []; constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private projectService: ProjectService, - private symbolService: SymbolService, - private nodeService: NodeService, - private linkService: LinkService, - private progressService: ProgressService, - private projectWebServiceHandler: ProjectWebServiceHandler, - private mapChangeDetectorRef: MapChangeDetectorRef, - private nodeWidget: NodeWidget, - protected nodesDataSource: NodesDataSource, - protected linksDataSource: LinksDataSource, - protected drawingsDataSource: DrawingsDataSource, - ) { - this.selectionManager = new SelectionManager( - this.nodesDataSource, this.linksDataSource, this.drawingsDataSource, new InRectangleHelper()); - - this.subscriptions = []; - } + private route: ActivatedRoute, + private serverService: ServerService, + private projectService: ProjectService, + private symbolService: SymbolService, + private nodeService: NodeService, + private linkService: LinkService, + private progressService: ProgressService, + private projectWebServiceHandler: ProjectWebServiceHandler, + private mapChangeDetectorRef: MapChangeDetectorRef, + private nodeWidget: NodeWidget, + private selectionManager: SelectionManager, + protected nodesDataSource: NodesDataSource, + protected linksDataSource: LinksDataSource, + protected drawingsDataSource: DrawingsDataSource, + ) {} ngOnInit() { this.progressService.activate();