From 92d6c8e41184ec6c611450eb002bc216085a87d5 Mon Sep 17 00:00:00 2001 From: Piotr Pekala Date: Wed, 12 Dec 2018 03:34:44 -0800 Subject: [PATCH] Reimplementation of adding text --- .../components/d3-map/d3-map.component.ts | 8 +++ .../text-adding/text-adding.component.ts | 23 +++--- .../text-editing/text-editing.component.ts | 4 -- src/app/cartography/d3-map.imports.ts | 2 + .../events/drawings-event-source.ts | 5 +- src/app/cartography/events/event-source.ts | 10 ++- .../tools/text-adding-tool.spec.ts | 0 src/app/cartography/tools/text-adding-tool.ts | 62 ++++++++++++++++ .../project-map/project-map.component.html | 1 + .../project-map/project-map.component.ts | 70 ++++++------------- 10 files changed, 121 insertions(+), 64 deletions(-) create mode 100644 src/app/cartography/tools/text-adding-tool.spec.ts create mode 100644 src/app/cartography/tools/text-adding-tool.ts diff --git a/src/app/cartography/components/d3-map/d3-map.component.ts b/src/app/cartography/components/d3-map/d3-map.component.ts index 29b25511..9af16712 100644 --- a/src/app/cartography/components/d3-map/d3-map.component.ts +++ b/src/app/cartography/components/d3-map/d3-map.component.ts @@ -23,6 +23,7 @@ import { MapSettingsManager } from '../../managers/map-settings-manager'; import { TextEditingTool } from '../../tools/text-editing-tool'; import { TextAddingComponent } from '../text-adding/text-adding.component'; import { Server } from '../../../models/server'; +import { TextAddingTool } from '../../tools/text-adding-tool'; @Component({ @@ -66,6 +67,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { protected interfaceLabelWidget: InterfaceLabelWidget, protected selectionToolWidget: SelectionTool, protected movingToolWidget: MovingTool, + protected textAddingToolWidget: TextAddingTool, protected textEditingToolWidget: TextEditingTool, public graphLayout: GraphLayout, ) { @@ -91,6 +93,12 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { this.mapChangeDetectorRef.detectChanges(); } + @Input('text-adding-tool') + set textAddingTool(value){ + this.textAddingToolWidget.setEnabled(value); + this.mapChangeDetectorRef.detectChanges(); + } + @Input('text-editing-tool') set textEditingTool(value){ this.textEditingToolWidget.setEnabled(value); diff --git a/src/app/cartography/components/text-adding/text-adding.component.ts b/src/app/cartography/components/text-adding/text-adding.component.ts index 24651934..b0ca8d39 100644 --- a/src/app/cartography/components/text-adding/text-adding.component.ts +++ b/src/app/cartography/components/text-adding/text-adding.component.ts @@ -1,24 +1,31 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, OnDestroy } from "@angular/core"; import { select } from 'd3-selection'; import { Context } from "../../models/context"; +import { TextAddingTool } from '../../tools/text-adding-tool'; +import { Subscription } from 'rxjs'; +import { DrawingsEventSource } from '../../events/drawings-event-source'; +import { TextAddedDataEvent } from '../../events/event-source'; @Component({ selector: 'app-text-adding', template: ``, styleUrls: ['./text-adding.component.scss'] }) -export class TextAddingComponent implements OnInit { - public isEnabled: boolean = true; +export class TextAddingComponent implements OnInit, OnDestroy{ + textAddingFinished: Subscription; constructor( - private context: Context + private textAddingTool: TextAddingTool, + private drawingEventSource: DrawingsEventSource ){} - ngOnInit(){ - + ngOnInit() { + this.textAddingFinished = this.textAddingTool.addingFinished.subscribe((evt: TextAddedDataEvent) => { + this.drawingEventSource.textAdded.emit(evt); + }) } - addingTextSelected(){ - //here will be moved addText in projectMapComponent + ngOnDestroy() { + this.textAddingFinished.unsubscribe(); } } diff --git a/src/app/cartography/components/text-editing/text-editing.component.ts b/src/app/cartography/components/text-editing/text-editing.component.ts index 8e981f86..9aa96a78 100644 --- a/src/app/cartography/components/text-editing/text-editing.component.ts +++ b/src/app/cartography/components/text-editing/text-editing.component.ts @@ -23,10 +23,6 @@ export class TextEditingComponent implements OnInit, OnDestroy{ }); } - onTextAddingChosen() { - - } - ngOnDestroy() { this.textEditingFinished.unsubscribe(); } diff --git a/src/app/cartography/d3-map.imports.ts b/src/app/cartography/d3-map.imports.ts index 728a6af8..cc73faa4 100644 --- a/src/app/cartography/d3-map.imports.ts +++ b/src/app/cartography/d3-map.imports.ts @@ -5,6 +5,7 @@ import { DrawingsWidget } from './widgets/drawings'; import { DrawingLineWidget } from './widgets/drawing-line'; import { SelectionTool } from './tools/selection-tool'; import { MovingTool } from './tools/moving-tool'; +import {TextAddingTool} from './tools/text-adding-tool'; import {TextEditingTool} from './tools/text-editing-tool'; import { LayersWidget } from './widgets/layers'; import { LinkWidget } from './widgets/link'; @@ -29,6 +30,7 @@ export const D3_MAP_IMPORTS = [ DrawingLineWidget, SelectionTool, MovingTool, + TextAddingTool, TextEditingTool, LayersWidget, LinkWidget, diff --git a/src/app/cartography/events/drawings-event-source.ts b/src/app/cartography/events/drawings-event-source.ts index 1f25e781..3b34965e 100644 --- a/src/app/cartography/events/drawings-event-source.ts +++ b/src/app/cartography/events/drawings-event-source.ts @@ -1,5 +1,5 @@ import { Injectable, EventEmitter } from "@angular/core"; -import { DraggedDataEvent, ResizedDataEvent } from "./event-source"; +import { DraggedDataEvent, ResizedDataEvent, TextAddedDataEvent, TextEditedDataEvent } from "./event-source"; import { MapDrawing } from "../models/map/map-drawing"; @@ -7,5 +7,6 @@ import { MapDrawing } from "../models/map/map-drawing"; export class DrawingsEventSource { public dragged = new EventEmitter>(); public resized = new EventEmitter>(); - public textEdited = new EventEmitter(); + public textAdded = new EventEmitter(); + public textEdited = new EventEmitter(); } diff --git a/src/app/cartography/events/event-source.ts b/src/app/cartography/events/event-source.ts index a9203860..a3487a89 100644 --- a/src/app/cartography/events/event-source.ts +++ b/src/app/cartography/events/event-source.ts @@ -17,7 +17,7 @@ export class ResizedDataEvent { public y: number, public width: number, public height: number - ) {} + ) {} } export class ClickedDataEvent { @@ -28,6 +28,14 @@ export class ClickedDataEvent { ) {} } +export class TextAddedDataEvent { + constructor( + public savedText: string, + public x: number, + public y: number + ) {} +} + export class TextEditedDataEvent { constructor( public textDrawingId: string, diff --git a/src/app/cartography/tools/text-adding-tool.spec.ts b/src/app/cartography/tools/text-adding-tool.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/cartography/tools/text-adding-tool.ts b/src/app/cartography/tools/text-adding-tool.ts new file mode 100644 index 00000000..b9bd718c --- /dev/null +++ b/src/app/cartography/tools/text-adding-tool.ts @@ -0,0 +1,62 @@ +import { Injectable, EventEmitter } from "@angular/core"; +import { TextAddedDataEvent } from '../events/event-source'; + + +@Injectable() +export class TextAddingTool { + private enabled; + private listener: Function; + public addingFinished = new EventEmitter(); + + public setEnabled(enabled){ + this.enabled = enabled; + if (enabled){ + this.activate(); + } else { + this.deactivate(); + } + } + + private deactivate(){ + var map = document.getElementsByClassName('map')[0]; + map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject); + } + + private activate(){ + 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(); + document.body.style.cursor = "text"; + + div.addEventListener("focusout", () => { + let savedText = div.innerText; + this.addingFinished.emit(new TextAddedDataEvent(savedText, event.clientX, event.clientY)); + + document.body.style.cursor = "default"; + div.remove(); + }); + } + + map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject); + this.listener = addTextListener; + map.addEventListener('click', this.listener as EventListenerOrEventListenerObject, {once : true}); + } +} diff --git a/src/app/components/project-map/project-map.component.html b/src/app/components/project-map/project-map.component.html index 28f40f42..5f866def 100644 --- a/src/app/components/project-map/project-map.component.html +++ b/src/app/components/project-map/project-map.component.html @@ -11,6 +11,7 @@ [selection-tool]="tools.selection" [moving-tool]="tools.moving" [text-editing-tool]="tools.text_editing" + [text-adding-tool]="drawTools.isAddingTextChosen" [draw-link-tool]="tools.draw_link" [readonly]="inReadOnlyMode" (nodeDragged)="onNodeDragged($event)" diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index 7aaf15ee..13308397 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -26,7 +26,7 @@ import { MapChangeDetectorRef } from '../../cartography/services/map-change-dete import { NodeContextMenu } from '../../cartography/events/nodes'; import { MapLinkCreated } from '../../cartography/events/links'; import { NodeWidget } from '../../cartography/widgets/node'; -import { DraggedDataEvent, ResizedDataEvent, TextEditedDataEvent } from '../../cartography/events/event-source'; +import { DraggedDataEvent, ResizedDataEvent, TextEditedDataEvent, TextAddedDataEvent } from '../../cartography/events/event-source'; import { DrawingService } from '../../services/drawing.service'; import { MapNodeToNodeConverter } from '../../cartography/converters/map/map-node-to-node-converter'; import { NodesEventSource } from '../../cartography/events/nodes-event-source'; @@ -194,6 +194,10 @@ export class ProjectMapComponent implements OnInit, OnDestroy { this.drawingsEventSource.resized.subscribe((evt) => this.onDrawingResized(evt)) ); + this.subscriptions.push( + this.drawingsEventSource.textAdded.subscribe((evt) => this.onTextAdded(evt)) + ); + this.subscriptions.push( this.drawingsEventSource.textEdited.subscribe((evt) => this.onTextEdited(evt)) ); @@ -352,6 +356,21 @@ export class ProjectMapComponent implements OnInit, OnDestroy { }); } + public onTextAdded(evt: TextAddedDataEvent){ + this.resetDrawToolChoice(); + + let drawing = this.getDrawingMock("text", evt.savedText); + (drawing.element as TextElement).text = evt.savedText; + let svgText = this.mapDrawingToSvgConverter.convert(drawing); + + this.drawingService + .add(this.server, this.project.project_id, evt.x - this.mapChild.context.getZeroZeroTransformationPoint().x, evt.y - this.mapChild.context.getZeroZeroTransformationPoint().y, svgText) + .subscribe((serverDrawing: Drawing) => { + document.body.style.cursor = "default"; + this.drawingsDataSource.add(serverDrawing); + }); + } + public onTextEdited(evt: TextEditedDataEvent){ let mapDrawing: MapDrawing = new MapDrawing(); mapDrawing.element = evt.textElement; @@ -510,7 +529,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { break; case "text": let textElement = new TextElement(); - textElement.height = 100; //should be calculated + textElement.height = 100; textElement.width = 100; textElement.text = text; textElement.fill = "#000000"; @@ -531,55 +550,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy { if (!this.drawTools.isAddingTextChosen){ this.resetDrawToolChoice(); this.drawTools.isAddingTextChosen = true; - 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 - 10).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"; - - div.addEventListener("focusout", () => { - let savedText = div.innerText; - - let drawing = this.getDrawingMock("text", savedText); - (drawing.element as TextElement).text = savedText; - let svgText = this.mapDrawingToSvgConverter.convert(drawing); - - this.drawingService - .add(this.server, this.project.project_id, event.clientX - this.mapChild.context.getZeroZeroTransformationPoint().x, event.clientY - this.mapChild.context.getZeroZeroTransformationPoint().y, svgText) - .subscribe((serverDrawing: Drawing) => { - document.body.style.cursor = "default"; - div.remove(); - this.drawingsDataSource.add(serverDrawing); - }); - }); - - this.resetDrawToolChoice(); - } - - map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject); - this.drawListener = addTextListener; - map.addEventListener('click', this.drawListener as EventListenerOrEventListenerObject, {once : true}); } else { this.resetDrawToolChoice(); - var map = document.getElementsByClassName('map')[0]; - map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject); } }