UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

136 lines (128 loc) 6.08 kB
import { DiagramControl } from "../Diagram"; import { DiagramItem } from "../Model/DiagramItem"; import { ChangeShapeTextHistoryItem } from "../History/Properties/ChangeShapeTextHistoryItem"; import { DiagramMouseEvent, MouseEventElementType, DiagramKeyboardEvent, DiagramEvent, DiagramFocusEvent } from "./Event"; import { ModifierKey } from "@devexpress/utils/lib/utils/key"; import { Shape } from "../Model/Shapes/Shape"; import { Connector } from "../Model/Connectors/Connector"; import { ChangeConnectorTextHistoryItem } from "../History/Properties/ChangeConnectorTextHistoryItem"; export class TextInputHandler { control: DiagramControl; textInputItem: DiagramItem; textInputPosition: number; constructor(control: DiagramControl) { this.control = control; } startTextInput(item: DiagramItem, position?: number): void { if(item.isLocked || !item.enableText || !item.allowEditText || this.control.settings.readOnly || !this.canFinishTextEditing()) return; this.control.beginUpdate(); this.textInputItem = item; let allowed = true; if(this.textInputItem instanceof Shape) { const textRect = this.textInputItem.textEditRectangle; allowed = this.control.permissionsProvider.canChangeShapeText(this.textInputItem); if(allowed) this.control.eventManager.raiseTextInputStart(this.textInputItem, this.textInputItem.text, textRect.createPosition(), textRect.createSize()); } else if(this.textInputItem instanceof Connector) { this.textInputPosition = position; allowed = this.control.permissionsProvider.canChangeConnectorText(this.textInputItem, this.textInputPosition); if(allowed) this.control.eventManager.raiseTextInputStart(this.textInputItem, this.textInputItem.getText(this.textInputPosition), this.textInputItem.getTextPoint(this.textInputPosition)); } if(!allowed) { delete this.textInputItem; this.control.endUpdate(); } } endTextInput(captureFocus?: boolean) { const textInputItem = this.textInputItem; delete this.textInputItem; this.control.eventManager.raiseTextInputEnd(textInputItem, captureFocus); this.control.endUpdate(); this.control.barManager.updateItemsState(); } raiseTextInputPermissionsCheck(allowed: boolean): void { this.control.eventManager.raiseTextInputPermissionsCheck(this.textInputItem, allowed); } applyTextInput(text: string, captureFocus?: boolean): void { if(!this.canFinishTextEditing(text)) return; const textInputItem = this.textInputItem; const textInputPosition = this.textInputPosition; this.endTextInput(captureFocus); if(textInputItem instanceof Shape) { if(textInputItem.text !== text) this.control.history.addAndRedo( new ChangeShapeTextHistoryItem(textInputItem, text) ); } else if(textInputItem instanceof Connector) if(textInputItem.getText(textInputPosition) !== text) this.control.history.addAndRedo( new ChangeConnectorTextHistoryItem(textInputItem, textInputPosition, text) ); } canFinishTextEditing(text?: string): boolean { let allowed = true; if(this.isTextInputActive()) { const newText = text || this.getTextInputElementValue(); if(this.textInputItem instanceof Shape) allowed = this.control.permissionsProvider.canApplyShapeTextChange(this.textInputItem as Shape, newText); else if(this.textInputItem instanceof Connector) allowed = this.control.permissionsProvider.canApplyConnectorTextChange(this.textInputItem as Connector, this.textInputPosition, newText); this.raiseTextInputPermissionsCheck(allowed); } return allowed; } private getTextInputElementValue() { if(this.control.render) return this.control.render.input.getTextInputElementValue(); return ""; } cancelTextInput(): void { this.raiseTextInputPermissionsCheck(true); this.endTextInput(true); } isTextInputActive(): boolean { return this.textInputItem !== undefined; } processDblClick(evt: DiagramMouseEvent): void { if(evt.source.type === MouseEventElementType.Shape) { const shape = this.control.model.findShape(evt.source.key); this.startTextInput(shape); } else if(evt.source.type === MouseEventElementType.Connector) { const connector = this.control.model.findConnector(evt.source.key); const position = connector.getTextPositionByPoint(evt.modelPoint); this.startTextInput(connector, position); } else if(evt.source.type === MouseEventElementType.ConnectorText) { const connector = this.control.model.findConnector(evt.source.key); const position = parseFloat(evt.source.value); this.startTextInput(connector, position); } } onDblClick(evt: DiagramMouseEvent) { setTimeout(() => { this.processDblClick(evt); }, 10); } onKeyDown(evt: DiagramKeyboardEvent) { if(!this.isTextInputActive()) return; if(evt.keyCode === 13 && this.hasCtrlModifier(evt.modifiers)) { evt.preventDefault = true; this.applyTextInput(evt.inputText, true); } if(evt.keyCode === 27) this.cancelTextInput(); } onBlur(evt: DiagramFocusEvent) { if(this.isTextInputActive()) this.applyTextInput(evt.inputText); } onFocus(evt: DiagramEvent) { } private hasCtrlModifier(key: ModifierKey): boolean { return (key & ModifierKey.Ctrl) > 0; } }