mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-18 18:56:26 +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 textAdded = new EventEmitter<TextAddedDataEvent>();
|
||||
public textEdited = new EventEmitter<TextEditedDataEvent>();
|
||||
public textSaved = new EventEmitter<any>();
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
import { Injectable, EventEmitter } from "@angular/core";
|
||||
import { TextAddedDataEvent } from '../events/event-source';
|
||||
import { DrawingsEventSource } from '../events/drawings-event-source';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class TextAddingTool {
|
||||
private enabled;
|
||||
private listener: Function;
|
||||
private temporaryElement: HTMLDivElement;
|
||||
public addingFinished = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private drawingEventSource: DrawingsEventSource
|
||||
){}
|
||||
|
||||
public setEnabled(enabled){
|
||||
this.enabled = enabled;
|
||||
if (enabled){
|
||||
this.activate();
|
||||
} else {
|
||||
@ -26,32 +30,21 @@ export class TextAddingTool {
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
|
||||
let addTextListener = (event: MouseEvent) => {
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.style.width = "fit-content";
|
||||
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();
|
||||
this.temporaryElement = this.getTemporaryElement(event.clientX, event.clientY);
|
||||
document.body.appendChild(this.temporaryElement);
|
||||
this.temporaryElement.focus();
|
||||
document.body.style.cursor = "text";
|
||||
|
||||
div.addEventListener("focusout", () => {
|
||||
let savedText = div.innerText;
|
||||
this.temporaryElement.addEventListener("focusout", () => {
|
||||
let savedText = this.temporaryElement.innerText;
|
||||
this.addingFinished.emit(new TextAddedDataEvent(savedText, event.clientX, event.clientY));
|
||||
|
||||
this.drawingEventSource.textSaved.subscribe((evt:boolean) => {
|
||||
if(evt){
|
||||
this.temporaryElement.remove();
|
||||
document.body.style.cursor = "default";
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,4 +52,21 @@ export class TextAddingTool {
|
||||
this.listener = addTextListener;
|
||||
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 { TextElement } from '../models/drawings/text-element';
|
||||
import { TextEditedDataEvent } from '../events/event-source';
|
||||
import { DrawingsEventSource } from '../events/drawings-event-source';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -10,8 +11,13 @@ export class TextEditingTool {
|
||||
private enabled = true;
|
||||
private editingDrawingId: string;
|
||||
private editedElement: any;
|
||||
private temporaryElement: HTMLDivElement;
|
||||
public editingFinished = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private drawingEventSource: DrawingsEventSource
|
||||
){}
|
||||
|
||||
public setEnabled(enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
@ -34,45 +40,44 @@ export class TextEditingTool {
|
||||
|
||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute("drawing_id");
|
||||
|
||||
select(textElements[index].parentElement.parentElement.parentElement)
|
||||
.append("foreignObject")
|
||||
.attr("width", '1000px')
|
||||
.attr("min-width", 'fit-content')
|
||||
.attr("height", '100px')
|
||||
.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;
|
||||
var splitted = textElements[index].parentElement.getAttribute("transform").split(/\(|\)/);
|
||||
var x = Number(splitted[1].split(/,/)[0]);
|
||||
var y = Number(splitted[1].split(/,/)[1]);
|
||||
console.log(x);
|
||||
console.log(y);
|
||||
|
||||
this.temporaryElement = document.createElement('div');
|
||||
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;
|
||||
|
||||
this.temporaryElement.addEventListener("focusout", () => {
|
||||
let savedText = this.temporaryElement.innerText;
|
||||
this.editingFinished.emit(new TextEditedDataEvent(this.editingDrawingId, savedText, this.editedElement));
|
||||
|
||||
var temporaryElement = document.getElementById("temporaryText") as HTMLElement;
|
||||
temporaryElement.remove();
|
||||
this.drawingEventSource.textSaved.subscribe((evt:boolean) => {
|
||||
if(evt){
|
||||
this.temporaryElement.remove();
|
||||
document.body.style.cursor = "default";
|
||||
}
|
||||
});
|
||||
|
||||
selection.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||
.attr("visibility", "visible")
|
||||
.classed("editingMode", false);
|
||||
});
|
||||
|
||||
var txtInside = document.getElementsByClassName("temporaryTextInside")[0] as HTMLElement;
|
||||
txtInside.focus();
|
||||
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();
|
||||
|
||||
let drawing = this.getDrawingMock("text", evt.savedText);
|
||||
@ -368,10 +368,11 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
.subscribe((serverDrawing: Drawing) => {
|
||||
document.body.style.cursor = "default";
|
||||
this.drawingsDataSource.add(serverDrawing);
|
||||
this.drawingsEventSource.textSaved.emit(true);
|
||||
});
|
||||
}
|
||||
|
||||
public onTextEdited(evt: TextEditedDataEvent){
|
||||
public onTextEdited(evt: TextEditedDataEvent) {
|
||||
let mapDrawing: MapDrawing = new MapDrawing();
|
||||
mapDrawing.element = evt.textElement;
|
||||
(mapDrawing.element as TextElement).text = evt.editedText;
|
||||
@ -383,6 +384,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
.updateText(this.server, drawing, svgString)
|
||||
.subscribe((serverDrawing: Drawing) => {
|
||||
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});
|
||||
}
|
||||
|
||||
public resetDrawToolChoice(){
|
||||
public resetDrawToolChoice() {
|
||||
this.drawTools.isRectangleChosen = false;
|
||||
this.drawTools.isEllipseChosen = false;
|
||||
this.drawTools.isLineChosen = false;
|
||||
@ -473,14 +475,14 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
this.selectedDrawing = "";
|
||||
}
|
||||
|
||||
public hideMenu(){
|
||||
public hideMenu() {
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||
this.resetDrawToolChoice();
|
||||
this.drawTools.visibility = false;
|
||||
}
|
||||
|
||||
public showMenu(){
|
||||
public showMenu() {
|
||||
setTimeout(() => {
|
||||
this.drawTools.visibility = true;
|
||||
},
|
||||
@ -546,10 +548,12 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
return mapDrawing;
|
||||
}
|
||||
|
||||
public addText(){
|
||||
public addText() {
|
||||
if (!this.drawTools.isAddingTextChosen){
|
||||
this.resetDrawToolChoice();
|
||||
this.drawTools.isAddingTextChosen = true;
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||
} else {
|
||||
this.resetDrawToolChoice();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user