New approach for draggable

This commit is contained in:
ziajka 2018-11-07 14:44:17 +01:00
parent 2f822580a9
commit b57bc7370b
7 changed files with 147 additions and 26 deletions

@ -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 ]

@ -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) {

@ -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<T> extends DraggableEvent {
constructor(
public datum: T
){
super();
}
}
export class DraggableDrag<T> extends DraggableEvent {
constructor(
public datum: T
){
super();
}
}
export class DraggableEnd<T> extends DraggableEvent {
constructor(
public datum: T
){
super();
}
}
export class Draggable<GElement extends DraggedElementBaseType, Datum> {
public start = new EventEmitter<DraggableStart<Datum>>();
public drag = new EventEmitter<DraggableStart<Datum>>();
public end = new EventEmitter<DraggableStart<Datum>>();
public call(selection) {
selection.call(this.behaviour());
}
private behaviour() {
return drag<GElement, Datum>()
.on('start', (datum: Datum) => {
const evt = new DraggableStart<Datum>(datum);
evt.dx = event.dx;
evt.dy = event.dy;
this.start.emit(evt);
})
.on('drag', (datum: Datum) => {
const evt = new DraggableDrag<Datum>(datum);
evt.dx = event.dx;
evt.dy = event.dy;
this.drag.emit(evt);
})
.on('end', (datum: Datum) => {
const evt = new DraggableEnd<Datum>(datum);
evt.dx = event.dx;
evt.dy = event.dy;
this.end.emit(evt);
});
}
}

@ -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<Drawing>) => {
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<Drawing>) => {
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();
}
}

@ -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<SVGGElement, Drawing>();
// public onContextMenu = new EventEmitter<NodeContextMenu>();
// public onDrawingClicked = new EventEmitter<NodeClicked>();
// public onDrawingDragged = new EventEmitter<NodeDragged>();
// public onDrawingDragging = new EventEmitter<NodeDragging>();
constructor(
private svgToDrawingConverter: SvgToDrawingConverter,
private textDrawingWidget: TextDrawingWidget,
@ -69,5 +79,6 @@ export class DrawingsWidget implements Widget {
.exit()
.remove();
this.draggable.call(drawing_merge);
}
}

@ -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"

@ -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();