mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-11 13:03:05 +00:00
Reimplementation of text editing
This commit is contained in:
parent
92d6c8e411
commit
f0582e6a9e
@ -9,4 +9,5 @@ export class DrawingsEventSource {
|
|||||||
public resized = new EventEmitter<ResizedDataEvent<MapDrawing>>();
|
public resized = new EventEmitter<ResizedDataEvent<MapDrawing>>();
|
||||||
public textAdded = new EventEmitter<TextAddedDataEvent>();
|
public textAdded = new EventEmitter<TextAddedDataEvent>();
|
||||||
public textEdited = new EventEmitter<TextEditedDataEvent>();
|
public textEdited = new EventEmitter<TextEditedDataEvent>();
|
||||||
|
public textSaved = new EventEmitter<any>();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import { Injectable, EventEmitter } from "@angular/core";
|
import { Injectable, EventEmitter } from "@angular/core";
|
||||||
import { TextAddedDataEvent } from '../events/event-source';
|
import { TextAddedDataEvent } from '../events/event-source';
|
||||||
|
import { DrawingsEventSource } from '../events/drawings-event-source';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TextAddingTool {
|
export class TextAddingTool {
|
||||||
private enabled;
|
|
||||||
private listener: Function;
|
private listener: Function;
|
||||||
|
private temporaryElement: HTMLDivElement;
|
||||||
public addingFinished = new EventEmitter<any>();
|
public addingFinished = new EventEmitter<any>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private drawingEventSource: DrawingsEventSource
|
||||||
|
){}
|
||||||
|
|
||||||
public setEnabled(enabled){
|
public setEnabled(enabled){
|
||||||
this.enabled = enabled;
|
|
||||||
if (enabled){
|
if (enabled){
|
||||||
this.activate();
|
this.activate();
|
||||||
} else {
|
} else {
|
||||||
@ -26,37 +30,43 @@ export class TextAddingTool {
|
|||||||
var map = document.getElementsByClassName('map')[0];
|
var map = document.getElementsByClassName('map')[0];
|
||||||
|
|
||||||
let addTextListener = (event: MouseEvent) => {
|
let addTextListener = (event: MouseEvent) => {
|
||||||
|
this.temporaryElement = this.getTemporaryElement(event.clientX, event.clientY);
|
||||||
var div = document.createElement('div');
|
document.body.appendChild(this.temporaryElement);
|
||||||
div.style.width = "fit-content";
|
this.temporaryElement.focus();
|
||||||
div.style.left = event.clientX.toString() + 'px';
|
|
||||||
div.style.top = (event.clientY).toString() + 'px';
|
|
||||||
div.style.position = "absolute";
|
|
||||||
div.style.zIndex = "99";
|
|
||||||
|
|
||||||
div.style.fontFamily = "Noto Sans";
|
|
||||||
div.style.fontSize = "11pt";
|
|
||||||
div.style.fontWeight = "bold";
|
|
||||||
div.style.color = "#000000";
|
|
||||||
|
|
||||||
div.setAttribute("contenteditable", "true");
|
|
||||||
|
|
||||||
document.body.appendChild(div);
|
|
||||||
div.innerText = "";
|
|
||||||
div.focus();
|
|
||||||
document.body.style.cursor = "text";
|
document.body.style.cursor = "text";
|
||||||
|
|
||||||
div.addEventListener("focusout", () => {
|
this.temporaryElement.addEventListener("focusout", () => {
|
||||||
let savedText = div.innerText;
|
let savedText = this.temporaryElement.innerText;
|
||||||
this.addingFinished.emit(new TextAddedDataEvent(savedText, event.clientX, event.clientY));
|
this.addingFinished.emit(new TextAddedDataEvent(savedText, event.clientX, event.clientY));
|
||||||
|
|
||||||
document.body.style.cursor = "default";
|
this.drawingEventSource.textSaved.subscribe((evt:boolean) => {
|
||||||
div.remove();
|
if(evt){
|
||||||
|
this.temporaryElement.remove();
|
||||||
|
document.body.style.cursor = "default";
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject);
|
map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject);
|
||||||
this.listener = addTextListener;
|
this.listener = addTextListener;
|
||||||
map.addEventListener('click', this.listener as EventListenerOrEventListenerObject, {once : true});
|
map.addEventListener('click', this.listener as EventListenerOrEventListenerObject, {once : true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTemporaryElement(x:number, y:number): HTMLDivElement{
|
||||||
|
var elem = document.createElement('div');
|
||||||
|
elem.style.width = "fit-content";
|
||||||
|
elem.style.left = x.toString() + 'px';
|
||||||
|
elem.style.top = y.toString() + 'px';
|
||||||
|
elem.style.position = "absolute";
|
||||||
|
elem.style.zIndex = "99";
|
||||||
|
elem.style.fontFamily = "Noto Sans";
|
||||||
|
elem.style.fontSize = "11pt";
|
||||||
|
elem.style.fontWeight = "bold";
|
||||||
|
elem.style.color = "#000000";
|
||||||
|
elem.setAttribute("contenteditable", "true");
|
||||||
|
elem.innerText = "";
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { SVGSelection } from '../models/types';
|
|||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import { TextElement } from '../models/drawings/text-element';
|
import { TextElement } from '../models/drawings/text-element';
|
||||||
import { TextEditedDataEvent } from '../events/event-source';
|
import { TextEditedDataEvent } from '../events/event-source';
|
||||||
|
import { DrawingsEventSource } from '../events/drawings-event-source';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -10,8 +11,13 @@ export class TextEditingTool {
|
|||||||
private enabled = true;
|
private enabled = true;
|
||||||
private editingDrawingId: string;
|
private editingDrawingId: string;
|
||||||
private editedElement: any;
|
private editedElement: any;
|
||||||
|
private temporaryElement: HTMLDivElement;
|
||||||
public editingFinished = new EventEmitter<any>();
|
public editingFinished = new EventEmitter<any>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private drawingEventSource: DrawingsEventSource
|
||||||
|
){}
|
||||||
|
|
||||||
public setEnabled(enabled) {
|
public setEnabled(enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
@ -34,45 +40,44 @@ export class TextEditingTool {
|
|||||||
|
|
||||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute("drawing_id");
|
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute("drawing_id");
|
||||||
|
|
||||||
select(textElements[index].parentElement.parentElement.parentElement)
|
var splitted = textElements[index].parentElement.getAttribute("transform").split(/\(|\)/);
|
||||||
.append("foreignObject")
|
var x = Number(splitted[1].split(/,/)[0]);
|
||||||
.attr("width", '1000px')
|
var y = Number(splitted[1].split(/,/)[1]);
|
||||||
.attr("min-width", 'fit-content')
|
console.log(x);
|
||||||
.attr("height", '100px')
|
console.log(y);
|
||||||
.attr("id", "temporaryText")
|
|
||||||
.attr("transform", textElements[index].parentElement.getAttribute("transform"))
|
|
||||||
.append("xhtml:span")
|
|
||||||
.attr("width", "fit-content")
|
|
||||||
.attr("height", "fit-content")
|
|
||||||
.attr("class", "temporaryTextInside")
|
|
||||||
.attr('style', () => {
|
|
||||||
const styles: string[] = [];
|
|
||||||
styles.push(`white-space: pre-line`)
|
|
||||||
styles.push(`outline: 0px solid transparent`)
|
|
||||||
styles.push(`font-family: ${elem.font_family}`)
|
|
||||||
styles.push(`font-size: ${elem.font_size}pt!important`);
|
|
||||||
styles.push(`font-weight: ${elem.font_weight}`)
|
|
||||||
styles.push(`color: ${elem.fill}`);
|
|
||||||
return styles.join("; ");
|
|
||||||
})
|
|
||||||
.attr('text-decoration', elem.text_decoration)
|
|
||||||
.attr('contenteditable', 'true')
|
|
||||||
.text(elem.text)
|
|
||||||
.on("focusout", () => {
|
|
||||||
let temporaryText = document.getElementsByClassName("temporaryTextInside")[0] as HTMLElement;
|
|
||||||
let savedText = temporaryText.innerText;
|
|
||||||
this.editingFinished.emit(new TextEditedDataEvent(this.editingDrawingId, savedText, this.editedElement));
|
|
||||||
|
|
||||||
var temporaryElement = document.getElementById("temporaryText") as HTMLElement;
|
this.temporaryElement = document.createElement('div');
|
||||||
temporaryElement.remove();
|
this.temporaryElement.style.width = "fit-content";
|
||||||
|
this.temporaryElement.style.left = '100px';//x.toString() + 'px';
|
||||||
|
this.temporaryElement.style.top = '100px';//y.toString() + 'px';
|
||||||
|
this.temporaryElement.style.position = "absolute";
|
||||||
|
this.temporaryElement.style.zIndex = "99";
|
||||||
|
this.temporaryElement.style.fontFamily = elem.font_family;
|
||||||
|
this.temporaryElement.style.fontSize = `${elem.font_size}pt`;
|
||||||
|
this.temporaryElement.style.fontWeight = elem.font_weight;
|
||||||
|
this.temporaryElement.style.color = elem.fill;
|
||||||
|
this.temporaryElement.style.textDecoration = elem.text_decoration;
|
||||||
|
this.temporaryElement.setAttribute("contenteditable", "true");
|
||||||
|
this.temporaryElement.innerText = elem.text;
|
||||||
|
|
||||||
selection.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
this.temporaryElement.addEventListener("focusout", () => {
|
||||||
.attr("visibility", "visible")
|
let savedText = this.temporaryElement.innerText;
|
||||||
.classed("editingMode", false);
|
this.editingFinished.emit(new TextEditedDataEvent(this.editingDrawingId, savedText, this.editedElement));
|
||||||
|
|
||||||
|
this.drawingEventSource.textSaved.subscribe((evt:boolean) => {
|
||||||
|
if(evt){
|
||||||
|
this.temporaryElement.remove();
|
||||||
|
document.body.style.cursor = "default";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var txtInside = document.getElementsByClassName("temporaryTextInside")[0] as HTMLElement;
|
selection.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||||
txtInside.focus();
|
.attr("visibility", "visible")
|
||||||
|
.classed("editingMode", false);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(this.temporaryElement);
|
||||||
|
this.temporaryElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onTextAdded(evt: TextAddedDataEvent){
|
public onTextAdded(evt: TextAddedDataEvent) {
|
||||||
this.resetDrawToolChoice();
|
this.resetDrawToolChoice();
|
||||||
|
|
||||||
let drawing = this.getDrawingMock("text", evt.savedText);
|
let drawing = this.getDrawingMock("text", evt.savedText);
|
||||||
@ -368,10 +368,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe((serverDrawing: Drawing) => {
|
.subscribe((serverDrawing: Drawing) => {
|
||||||
document.body.style.cursor = "default";
|
document.body.style.cursor = "default";
|
||||||
this.drawingsDataSource.add(serverDrawing);
|
this.drawingsDataSource.add(serverDrawing);
|
||||||
|
this.drawingsEventSource.textSaved.emit(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onTextEdited(evt: TextEditedDataEvent){
|
public onTextEdited(evt: TextEditedDataEvent) {
|
||||||
let mapDrawing: MapDrawing = new MapDrawing();
|
let mapDrawing: MapDrawing = new MapDrawing();
|
||||||
mapDrawing.element = evt.textElement;
|
mapDrawing.element = evt.textElement;
|
||||||
(mapDrawing.element as TextElement).text = evt.editedText;
|
(mapDrawing.element as TextElement).text = evt.editedText;
|
||||||
@ -383,6 +384,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
.updateText(this.server, drawing, svgString)
|
.updateText(this.server, drawing, svgString)
|
||||||
.subscribe((serverDrawing: Drawing) => {
|
.subscribe((serverDrawing: Drawing) => {
|
||||||
this.drawingsDataSource.update(serverDrawing);
|
this.drawingsDataSource.update(serverDrawing);
|
||||||
|
this.drawingsEventSource.textSaved.emit(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +467,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
map.addEventListener('click', this.drawListener as EventListenerOrEventListenerObject, {once : true});
|
map.addEventListener('click', this.drawListener as EventListenerOrEventListenerObject, {once : true});
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetDrawToolChoice(){
|
public resetDrawToolChoice() {
|
||||||
this.drawTools.isRectangleChosen = false;
|
this.drawTools.isRectangleChosen = false;
|
||||||
this.drawTools.isEllipseChosen = false;
|
this.drawTools.isEllipseChosen = false;
|
||||||
this.drawTools.isLineChosen = false;
|
this.drawTools.isLineChosen = false;
|
||||||
@ -473,14 +475,14 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
this.selectedDrawing = "";
|
this.selectedDrawing = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideMenu(){
|
public hideMenu() {
|
||||||
var map = document.getElementsByClassName('map')[0];
|
var map = document.getElementsByClassName('map')[0];
|
||||||
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||||
this.resetDrawToolChoice();
|
this.resetDrawToolChoice();
|
||||||
this.drawTools.visibility = false;
|
this.drawTools.visibility = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public showMenu(){
|
public showMenu() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.drawTools.visibility = true;
|
this.drawTools.visibility = true;
|
||||||
},
|
},
|
||||||
@ -546,10 +548,12 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
return mapDrawing;
|
return mapDrawing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addText(){
|
public addText() {
|
||||||
if (!this.drawTools.isAddingTextChosen){
|
if (!this.drawTools.isAddingTextChosen){
|
||||||
this.resetDrawToolChoice();
|
this.resetDrawToolChoice();
|
||||||
this.drawTools.isAddingTextChosen = true;
|
this.drawTools.isAddingTextChosen = true;
|
||||||
|
var map = document.getElementsByClassName('map')[0];
|
||||||
|
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||||
} else {
|
} else {
|
||||||
this.resetDrawToolChoice();
|
this.resetDrawToolChoice();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user