mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-02 19:16:44 +00:00
Selection UI, Ref. #16
This commit is contained in:
parent
7589c46285
commit
ca1a6ad6cd
@ -2,7 +2,4 @@ svg {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
image.over {
|
|
||||||
fill: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
5
src/app/cartography/shared/tool.ts
Normal file
5
src/app/cartography/shared/tool.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import {SVGSelection} from "../../map/models/types";
|
||||||
|
|
||||||
|
export interface Tool {
|
||||||
|
connect(selection: SVGSelection);
|
||||||
|
}
|
@ -1,35 +1,45 @@
|
|||||||
import {SVGSelection} from "../../../map/models/types";
|
import {SVGSelection} from "../../../map/models/types";
|
||||||
import {mouse, select} from "d3-selection";
|
import {mouse, select} from "d3-selection";
|
||||||
|
import {Context} from "../../../map/models/context";
|
||||||
|
|
||||||
export class SelectionTool {
|
export class SelectionTool {
|
||||||
private selection: SVGSelection;
|
private selection: SVGSelection;
|
||||||
private path;
|
private path;
|
||||||
|
|
||||||
public connect(selection: SVGSelection) {
|
public connect(selection: SVGSelection, context: Context) {
|
||||||
const self = this;
|
const self = this;
|
||||||
this.selection = selection;
|
this.selection = selection;
|
||||||
const canvas = this.selection.select<SVGGElement>("g.canvas");
|
const canvas = this.selection.select<SVGGElement>("g.canvas");
|
||||||
|
|
||||||
if (!canvas.select<SVGGElement>("g.selection-tool").node()) {
|
if (!canvas.select<SVGGElement>("g.selection-line-tool").node()) {
|
||||||
const g = canvas.append<SVGGElement>('g');
|
const g = canvas.append<SVGGElement>('g');
|
||||||
g.attr("class", "selection-line-tool");
|
g.attr("class", "selection-line-tool");
|
||||||
|
|
||||||
this.path = g.append("path");
|
this.path = g.append("path");
|
||||||
this.path.attr("class", "selection").attr("visibility", "hidden");
|
this.path
|
||||||
|
.attr("class", "selection")
|
||||||
|
.attr("visibility", "hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transformation = (p) => {
|
||||||
|
const transformation_point = context.getZeroZeroTransformationPoint();
|
||||||
|
return [p[0] - transformation_point.x, p[1] - transformation_point.y];
|
||||||
|
};
|
||||||
|
|
||||||
selection.on("mousedown", function() {
|
selection.on("mousedown", function() {
|
||||||
const subject = select(window);
|
const subject = select(window);
|
||||||
const parent = this.parentNode;
|
const parent = this.parentElement;
|
||||||
|
|
||||||
const start = mouse(parent);
|
const start = transformation(mouse(parent));
|
||||||
self.startSelection(start);
|
self.startSelection(start);
|
||||||
subject
|
|
||||||
.on("mousemove.selection", function() {
|
subject
|
||||||
self.moveSelection(start, mouse(parent));
|
.on("mousemove.selection", function() {
|
||||||
}).on("mouseup.selection", function() {
|
self.moveSelection(start, transformation(mouse(parent)));
|
||||||
self.endSelection(start, mouse(parent));
|
}).on("mouseup.selection", function() {
|
||||||
subject.on("mousemove.selection", null).on("mouseup.selection", null);
|
self.endSelection(start, transformation(mouse(parent)));
|
||||||
});
|
subject.on("mousemove.selection", null).on("mouseup.selection", null);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,14 +48,20 @@ export class SelectionTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private startSelection(start) {
|
private startSelection(start) {
|
||||||
|
this.path
|
||||||
|
.attr("d", this.rect(start[0], start[1], 0, 0))
|
||||||
|
.attr("visibility", "visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
private moveSelection(start, move) {
|
private moveSelection(start, move) {
|
||||||
|
this.path.attr("d", this.rect(start[0], start[1], move[0] - start[0], move[1] - start[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private endSelection(start, end) {
|
private endSelection(start, end) {
|
||||||
|
this.path.attr("visibility", "hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
private rect(x: number, y: number, w: number, h: number) {
|
||||||
|
return "M" + [x, y] + " l" + [w, 0] + " l" + [0, h] + " l" + [-w, 0] + "z";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { Drawing } from "../models/drawing.model";
|
|||||||
import { DrawingsWidget } from "./drawings.widget";
|
import { DrawingsWidget } from "./drawings.widget";
|
||||||
import { DrawingLineWidget } from "./drawing-line.widget";
|
import { DrawingLineWidget } from "./drawing-line.widget";
|
||||||
import {SelectionTool} from "../tools/selection-tool";
|
import {SelectionTool} from "../tools/selection-tool";
|
||||||
|
import {Tool} from "../tool";
|
||||||
|
|
||||||
export class GraphLayout implements Widget {
|
export class GraphLayout implements Widget {
|
||||||
private nodes: Node[] = [];
|
private nodes: Node[] = [];
|
||||||
@ -80,24 +81,25 @@ export class GraphLayout implements Widget {
|
|||||||
this.nodesWidget.draw(canvas, this.nodes);
|
this.nodesWidget.draw(canvas, this.nodes);
|
||||||
this.drawingsWidget.draw(canvas, this.drawings);
|
this.drawingsWidget.draw(canvas, this.drawings);
|
||||||
|
|
||||||
this.drawingLineTool.connect(view);
|
|
||||||
this.selectionTool.connect(view);
|
|
||||||
|
|
||||||
const onZoom = function(this: SVGSVGElement) {
|
// this.drawingLineTool.connect(view, context);
|
||||||
const e: D3ZoomEvent<SVGSVGElement, any> = event;
|
this.selectionTool.connect(view, context);
|
||||||
if (self.centerZeroZeroPoint) {
|
|
||||||
canvas.attr(
|
|
||||||
'transform',
|
|
||||||
`translate(${context.getSize().width / 2 + e.transform.x}, ` +
|
|
||||||
`${context.getSize().height / 2 + e.transform.y}) scale(${e.transform.k})`);
|
|
||||||
} else {
|
|
||||||
canvas.attr('transform', e.transform.toString());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
view.call(zoom<SVGSVGElement, any>()
|
// const onZoom = function(this: SVGSVGElement) {
|
||||||
.scaleExtent([1 / 2, 8])
|
// const e: D3ZoomEvent<SVGSVGElement, any> = event;
|
||||||
.on('zoom', onZoom));
|
// if (self.centerZeroZeroPoint) {
|
||||||
|
// canvas.attr(
|
||||||
|
// 'transform',
|
||||||
|
// `translate(${context.getSize().width / 2 + e.transform.x}, ` +
|
||||||
|
// `${context.getSize().height / 2 + e.transform.y}) scale(${e.transform.k})`);
|
||||||
|
// } else {
|
||||||
|
// canvas.attr('transform', e.transform.toString());
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// view.call(zoom<SVGSVGElement, any>()
|
||||||
|
// .scaleExtent([1 / 2, 8])
|
||||||
|
// .on('zoom', onZoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import {Size} from "../../cartography/shared/models/size.model";
|
import {Size} from "../../cartography/shared/models/size.model";
|
||||||
import {Selection} from "d3-selection";
|
import {Selection} from "d3-selection";
|
||||||
|
import {Point} from "../../cartography/shared/models/point.model";
|
||||||
|
|
||||||
export class Context {
|
export class Context {
|
||||||
private size: Size;
|
private size: Size;
|
||||||
private root: Selection<SVGSVGElement, any, null, undefined>;
|
private root: Selection<SVGSVGElement, any, null, undefined>;
|
||||||
|
private centerZeroZeroPoint = true;
|
||||||
|
|
||||||
constructor(root: Selection<SVGSVGElement, any, null, undefined>) {
|
constructor(root: Selection<SVGSVGElement, any, null, undefined>) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -16,4 +18,8 @@ export class Context {
|
|||||||
public setSize(size: Size): void {
|
public setSize(size: Size): void {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getZeroZeroTransformationPoint() {
|
||||||
|
return new Point(this.getSize().width / 2., this.getSize().height / 2.);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,3 +46,23 @@ g.node text {
|
|||||||
svg image:hover, svg image.chosen {
|
svg image:hover, svg image.chosen {
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selection-line-tool .selection {
|
||||||
|
fill: #7ccbe1;
|
||||||
|
stroke: #66aec2 ;
|
||||||
|
fill-opacity: 0.3;
|
||||||
|
stroke-opacity: 0.7;
|
||||||
|
stroke-width: 1;
|
||||||
|
stroke-dasharray: 5, 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
g.node text,
|
||||||
|
.noselect {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user