mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-04 00:10:47 +00:00
New approach for draggable
This commit is contained in:
parent
2f822580a9
commit
b57bc7370b
@ -16,6 +16,7 @@ import { MapChangeDetectorRef } from './services/map-change-detector-ref';
|
|||||||
import { Context } from './models/context';
|
import { Context } from './models/context';
|
||||||
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
||||||
import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
||||||
|
import { MapListener } from './listeners/map-listener';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -39,6 +40,7 @@ import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
|||||||
MapChangeDetectorRef,
|
MapChangeDetectorRef,
|
||||||
CanvasSizeDetector,
|
CanvasSizeDetector,
|
||||||
Context,
|
Context,
|
||||||
|
MapListener,
|
||||||
...D3_MAP_IMPORTS
|
...D3_MAP_IMPORTS
|
||||||
],
|
],
|
||||||
exports: [ MapComponent ]
|
exports: [ MapComponent ]
|
||||||
|
@ -22,6 +22,7 @@ import { LinkCreated } from '../../events/links';
|
|||||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
import { NodeWidget } from '../../widgets/node';
|
import { NodeWidget } from '../../widgets/node';
|
||||||
|
import { MapListener } from '../../listeners/map-listener';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -35,8 +36,6 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Input() drawings: Drawing[] = [];
|
@Input() drawings: Drawing[] = [];
|
||||||
@Input() symbols: Symbol[] = [];
|
@Input() symbols: Symbol[] = [];
|
||||||
|
|
||||||
@Input('selection-manager') selectionManager: SelectionManager;
|
|
||||||
|
|
||||||
@Input() width = 1500;
|
@Input() width = 1500;
|
||||||
@Input() height = 600;
|
@Input() height = 600;
|
||||||
|
|
||||||
@ -60,6 +59,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
private context: Context,
|
private context: Context,
|
||||||
private mapChangeDetectorRef: MapChangeDetectorRef,
|
private mapChangeDetectorRef: MapChangeDetectorRef,
|
||||||
private canvasSizeDetector: CanvasSizeDetector,
|
private canvasSizeDetector: CanvasSizeDetector,
|
||||||
|
private mapListener: MapListener,
|
||||||
|
private selectionManager: SelectionManager,
|
||||||
protected element: ElementRef,
|
protected element: ElementRef,
|
||||||
protected nodesWidget: NodesWidget,
|
protected nodesWidget: NodesWidget,
|
||||||
protected nodeWidget: NodeWidget,
|
protected nodeWidget: NodeWidget,
|
||||||
@ -123,6 +124,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.onNodeClickedSubscription.unsubscribe();
|
this.onNodeClickedSubscription.unsubscribe();
|
||||||
this.onNodeDraggedSubscription.unsubscribe();
|
this.onNodeDraggedSubscription.unsubscribe();
|
||||||
this.onChangesDetected.unsubscribe();
|
this.onChangesDetected.unsubscribe();
|
||||||
|
this.mapListener.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -175,6 +177,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.mapListener.onInit(this.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createGraph(domElement: HTMLElement) {
|
public createGraph(domElement: HTMLElement) {
|
||||||
|
64
src/app/cartography/events/draggable.ts
Normal file
64
src/app/cartography/events/draggable.ts
Normal file
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
47
src/app/cartography/listeners/map-listener.ts
Normal file
47
src/app/cartography/listeners/map-listener.ts
Normal file
@ -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 { Widget } from "./widget";
|
||||||
import { Drawing } from "../models/drawing";
|
import { Drawing } from "../models/drawing";
|
||||||
@ -11,12 +11,22 @@ import { RectDrawingWidget } from "./drawings/rect-drawing";
|
|||||||
import { LineDrawingWidget } from "./drawings/line-drawing";
|
import { LineDrawingWidget } from "./drawings/line-drawing";
|
||||||
import { EllipseDrawingWidget } from "./drawings/ellipse-drawing";
|
import { EllipseDrawingWidget } from "./drawings/ellipse-drawing";
|
||||||
import { DrawingWidget } from "./drawings/drawing-widget";
|
import { DrawingWidget } from "./drawings/drawing-widget";
|
||||||
|
import { event } from "d3-selection";
|
||||||
|
import { D3DragEvent, drag } from "d3-drag";
|
||||||
|
import { Draggable } from "../events/draggable";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DrawingsWidget implements Widget {
|
export class DrawingsWidget implements Widget {
|
||||||
private drawingWidgets: DrawingWidget[] = [];
|
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(
|
constructor(
|
||||||
private svgToDrawingConverter: SvgToDrawingConverter,
|
private svgToDrawingConverter: SvgToDrawingConverter,
|
||||||
private textDrawingWidget: TextDrawingWidget,
|
private textDrawingWidget: TextDrawingWidget,
|
||||||
@ -69,5 +79,6 @@ export class DrawingsWidget implements Widget {
|
|||||||
.exit()
|
.exit()
|
||||||
.remove();
|
.remove();
|
||||||
|
|
||||||
|
this.draggable.call(drawing_merge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
[drawings]="drawings"
|
[drawings]="drawings"
|
||||||
[width]="project.scene_width"
|
[width]="project.scene_width"
|
||||||
[height]="project.scene_height"
|
[height]="project.scene_height"
|
||||||
[selection-manager]="selectionManager"
|
|
||||||
[show-interface-labels]="project.show_interface_labels"
|
[show-interface-labels]="project.show_interface_labels"
|
||||||
[selection-tool]="tools.selection"
|
[selection-tool]="tools.selection"
|
||||||
[moving-tool]="tools.moving"
|
[moving-tool]="tools.moving"
|
||||||
|
@ -57,13 +57,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
private inReadOnlyMode = false;
|
private inReadOnlyMode = false;
|
||||||
|
|
||||||
protected selectionManager: SelectionManager;
|
|
||||||
|
|
||||||
@ViewChild(MapComponent) mapChild: MapComponent;
|
@ViewChild(MapComponent) mapChild: MapComponent;
|
||||||
|
|
||||||
@ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent;
|
@ViewChild(NodeContextMenuComponent) nodeContextMenu: NodeContextMenuComponent;
|
||||||
|
|
||||||
private subscriptions: Subscription[];
|
private subscriptions: Subscription[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@ -76,15 +74,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private projectWebServiceHandler: ProjectWebServiceHandler,
|
private projectWebServiceHandler: ProjectWebServiceHandler,
|
||||||
private mapChangeDetectorRef: MapChangeDetectorRef,
|
private mapChangeDetectorRef: MapChangeDetectorRef,
|
||||||
private nodeWidget: NodeWidget,
|
private nodeWidget: NodeWidget,
|
||||||
|
private selectionManager: SelectionManager,
|
||||||
protected nodesDataSource: NodesDataSource,
|
protected nodesDataSource: NodesDataSource,
|
||||||
protected linksDataSource: LinksDataSource,
|
protected linksDataSource: LinksDataSource,
|
||||||
protected drawingsDataSource: DrawingsDataSource,
|
protected drawingsDataSource: DrawingsDataSource,
|
||||||
) {
|
) {}
|
||||||
this.selectionManager = new SelectionManager(
|
|
||||||
this.nodesDataSource, this.linksDataSource, this.drawingsDataSource, new InRectangleHelper());
|
|
||||||
|
|
||||||
this.subscriptions = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.progressService.activate();
|
this.progressService.activate();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user