mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-20 21:43:06 +00:00
Context menu preps, ref. #5
This commit is contained in:
parent
2eb7246f87
commit
5855587259
@ -40,6 +40,7 @@ import { AppComponent } from './app.component';
|
||||
import { MapComponent } from './cartography/map/map.component';
|
||||
import { CreateSnapshotDialogComponent, ProjectMapComponent } from './project-map/project-map.component';
|
||||
import { ServersComponent, AddServerDialogComponent } from './servers/servers.component';
|
||||
import { ContextMenuComponent } from './shared/context-menu/context-menu.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -53,6 +54,7 @@ import { ServersComponent, AddServerDialogComponent } from './servers/servers.co
|
||||
ProjectsComponent,
|
||||
DefaultLayoutComponent,
|
||||
ProgressDialogComponent,
|
||||
ContextMenuComponent,
|
||||
],
|
||||
imports: [
|
||||
NgbModule.forRoot(),
|
||||
|
@ -1 +1,15 @@
|
||||
<svg preserveAspectRatio="none"></svg>
|
||||
|
||||
<div class="context-menu" [style.left]="contextMenuLeft" [style.top]="contextMenuTop">
|
||||
<span [matMenuTriggerFor]="contextMenu"></span>
|
||||
<mat-menu #contextMenu="matMenu">
|
||||
<button mat-menu-item>
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
<span>Start</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon>stop</mat-icon>
|
||||
<span>Stop</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
Before Width: | Height: | Size: 39 B After Width: | Height: | Size: 435 B |
@ -1,3 +1,7 @@
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChange } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component, ElementRef, Input, NgZone, OnChanges, OnDestroy, OnInit, SimpleChange,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { D3, D3Service } from 'd3-ng2-service';
|
||||
import { Selection } from 'd3-selection';
|
||||
|
||||
@ -8,12 +12,22 @@ import { GraphLayout } from "../shared/widgets/graph.widget";
|
||||
import { Context } from "../../map/models/context";
|
||||
import { Size } from "../shared/models/size.model";
|
||||
import { Drawing } from "../shared/models/drawing.model";
|
||||
import {MatMenuTrigger} from "@angular/material";
|
||||
import {NodeOnContextMenuListener} from "../shared/widgets/nodes.widget";
|
||||
import {DomSanitizer} from "@angular/platform-browser";
|
||||
|
||||
class NodeOnContextMenu implements NodeOnContextMenuListener {
|
||||
constructor(private component: MapComponent) {}
|
||||
|
||||
onContextMenu() {
|
||||
this.component.contextMenu.openMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-map',
|
||||
templateUrl: '../../map/map.component.html',
|
||||
styleUrls: ['../../map/map.component.css']
|
||||
templateUrl: './map.component.html',
|
||||
styleUrls: ['./map.component.scss']
|
||||
})
|
||||
export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() nodes: Node[] = [];
|
||||
@ -21,10 +35,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() drawings: Drawing[] = [];
|
||||
@Input() width = 1500;
|
||||
@Input() height = 600;
|
||||
@Input() phylloRadius = 7;
|
||||
@Input() pointRadius= 2;
|
||||
@Input() windowFullSize = true;
|
||||
|
||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||
|
||||
private d3: D3;
|
||||
private parentNativeElement: any;
|
||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||
@ -32,19 +46,25 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private graphLayout: GraphLayout;
|
||||
private graphContext: Context;
|
||||
|
||||
public contextMenuTop;
|
||||
public contextMenuLeft;
|
||||
|
||||
constructor(protected element: ElementRef,
|
||||
protected d3Service: D3Service
|
||||
protected d3Service: D3Service,
|
||||
protected sanitizer: DomSanitizer,
|
||||
protected changeDetector: ChangeDetectorRef
|
||||
) {
|
||||
this.d3 = d3Service.getD3();
|
||||
this.parentNativeElement = element.nativeElement;
|
||||
|
||||
this.contextMenuLeft = this.sanitizer.bypassSecurityTrustStyle("0");
|
||||
this.contextMenuTop = this.sanitizer.bypassSecurityTrustStyle("0");
|
||||
}
|
||||
|
||||
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
|
||||
if (
|
||||
(changes['width'] && !changes['width'].isFirstChange()) ||
|
||||
(changes['height'] && !changes['height'].isFirstChange()) ||
|
||||
(changes['phylloRadius'] && !changes['phylloRadius'].isFirstChange()) ||
|
||||
(changes['pointRadius'] && !changes['pointRadius'].isFirstChange()) ||
|
||||
(changes['drawings'] && !changes['drawings'].isFirstChange()) ||
|
||||
(changes['nodes'] && !changes['nodes'].isFirstChange()) ||
|
||||
(changes['links'] && !changes['links'].isFirstChange())
|
||||
@ -89,7 +109,15 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
this.graphLayout = new GraphLayout();
|
||||
this.graphLayout.draw(this.svg, this.graphContext);
|
||||
// this.graphLayout.getNodesWidget().setOnContextMenuListener(new NodeOnContextMenu(self));
|
||||
this.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any) => {
|
||||
|
||||
this.contextMenuLeft = this.sanitizer.bypassSecurityTrustStyle(event.clientX + "px");
|
||||
this.contextMenuTop = this.sanitizer.bypassSecurityTrustStyle(event.clientY + "px");
|
||||
this.changeDetector.detectChanges();
|
||||
|
||||
this.contextMenu.openMenu();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -34,6 +34,10 @@ export class GraphLayout implements Widget {
|
||||
this.drawings = drawings;
|
||||
}
|
||||
|
||||
public getNodesWidget() {
|
||||
return this.nodesWidget;
|
||||
}
|
||||
|
||||
draw(view: SVGSelection, context: Context) {
|
||||
const self = this;
|
||||
|
||||
@ -59,7 +63,7 @@ export class GraphLayout implements Widget {
|
||||
|
||||
this.linksWidget.draw(canvas, this.links);
|
||||
this.nodesWidget.draw(canvas, this.nodes);
|
||||
this.drawingsWidget.draw(canvas, this.drawings)
|
||||
this.drawingsWidget.draw(canvas, this.drawings);
|
||||
|
||||
const onZoom = function(this: SVGSVGElement) {
|
||||
const e: D3ZoomEvent<SVGSVGElement, any> = event;
|
||||
|
@ -1,13 +1,31 @@
|
||||
import {Widget} from "./widget";
|
||||
import {Node} from "../models/node.model";
|
||||
import {SVGSelection} from "../../../map/models/types";
|
||||
import { event } from "d3-selection";
|
||||
import { D3} from "d3-ng2-service";
|
||||
|
||||
import {D3DragEvent} from "d3-drag";
|
||||
import {select} from "d3-selection";
|
||||
import {isUndefined} from "util";
|
||||
|
||||
export interface NodeOnContextMenuListener {
|
||||
onContextMenu(): void;
|
||||
};
|
||||
|
||||
export class NodesWidget implements Widget {
|
||||
private onContextMenuListener: NodeOnContextMenuListener;
|
||||
private onContextMenuCallback: (event: any) => void;
|
||||
|
||||
constructor() {}
|
||||
|
||||
public setOnContextMenuListener(onContextMenuListener: NodeOnContextMenuListener) {
|
||||
this.onContextMenuListener = onContextMenuListener;
|
||||
}
|
||||
|
||||
public setOnContextMenuCallback(onContextMenuCallback: (event: any) => void) {
|
||||
this.onContextMenuCallback = onContextMenuCallback;
|
||||
}
|
||||
|
||||
public draw(view: SVGSelection, nodes: Node[]) {
|
||||
const self = this;
|
||||
|
||||
@ -33,7 +51,17 @@ export class NodesWidget implements Widget {
|
||||
const node_image = node_enter.append<SVGImageElement>('image')
|
||||
.attr('xlink:href', (n: Node) => 'data:image/svg+xml;base64,' + btoa(n.icon.raw))
|
||||
.attr('width', (n: Node) => n.width)
|
||||
.attr('height', (n: Node) => n.height);
|
||||
.attr('height', (n: Node) => n.height)
|
||||
.on("contextmenu", function (n: Node, i: number) {
|
||||
// if (self.onContextMenuListener !== ) {
|
||||
// self.onContextMenuListener.onContextMenu();
|
||||
// }
|
||||
console.log(event);
|
||||
event.preventDefault();
|
||||
if (self.onContextMenuCallback !== null) {
|
||||
self.onContextMenuCallback(event);
|
||||
}
|
||||
});
|
||||
|
||||
node_enter.append<SVGCircleElement>('circle')
|
||||
.attr('class', 'node_point')
|
||||
|
@ -1,3 +0,0 @@
|
||||
svg {
|
||||
display: block;
|
||||
}
|
@ -1 +0,0 @@
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none"></svg>
|
Before Width: | Height: | Size: 83 B |
6
src/app/shared/context-menu/context-menu.component.html
Normal file
6
src/app/shared/context-menu/context-menu.component.html
Normal file
@ -0,0 +1,6 @@
|
||||
<span [matMenuTriggerFor]="contextMenu"></span>
|
||||
<button mat-button (contextmenu)="openContextMenu($event)">Context Menu</button>
|
||||
<mat-menu #contextMenu="matMenu">
|
||||
<button md-menu-item>Item 1</button>
|
||||
<button md-menu-item>Item 2</button>
|
||||
</mat-menu>
|
25
src/app/shared/context-menu/context-menu.component.spec.ts
Normal file
25
src/app/shared/context-menu/context-menu.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContextMenuComponent } from './context-menu.component';
|
||||
|
||||
describe('ContextMenuComponent', () => {
|
||||
let component: ContextMenuComponent;
|
||||
let fixture: ComponentFixture<ContextMenuComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ContextMenuComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ContextMenuComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
24
src/app/shared/context-menu/context-menu.component.ts
Normal file
24
src/app/shared/context-menu/context-menu.component.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatMenuTrigger } from '@angular/material';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-context-menu',
|
||||
templateUrl: './context-menu.component.html',
|
||||
styleUrls: ['./context-menu.component.scss']
|
||||
})
|
||||
export class ContextMenuComponent implements OnInit {
|
||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
openContextMenu(event) {
|
||||
event.preventDefault();
|
||||
this.contextMenu.openMenu();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user