UNPKG

@aurigma/design-atoms

Version:

Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.

813 lines 38.4 kB
import { PointF } from "@aurigma/design-atoms-model/Math"; import { EventObject, EventWithSenderArg } from "@aurigma/design-atoms-model/EventObject"; import { Environment } from "@aurigma/design-atoms-model/Utils/Environment"; import { ArchedTextItem, BoundedTextItem, CurvedTextItem, OverflowStrategy, PathBoundedTextItem, PlainTextItem, TextAlignment } from "@aurigma/design-atoms-model/Product/Items"; import { Keys } from "@aurigma/design-atoms-text/TextEditor"; import { DefaultStyleExtractor } from "@aurigma/design-atoms-text/Serialization/DefaultStyleExtractor"; import { ColorPalette } from "@aurigma/design-atoms-text/Serialization/Model/ColorPalette"; import { ParagraphAlignment } from "@aurigma/design-atoms-text/Model"; import { ListStyleSheetManagerFactory } from "@aurigma/design-atoms-text/TextEditor/Services"; import { TextWhizzWrapper } from "@aurigma/design-atoms-text/TextEditor/TextWhizz/TextWhizzWrapper"; import { MouseEventType } from "@aurigma/design-atoms-text/TextEditor/Enums/MouseEventType"; import { NewTextEditor } from "@aurigma/design-atoms-text/TextEditor/NewTextEditor"; import { NewBoundedTextItemHandler, NewCurvedTextItemHandler, NewPlainTextItemHandler, NewArchedTextItemHandler, } from "../ItemHandlers"; import { TextStateType } from "./TextStateType"; import { ItemUtils } from "../Utils/ItemUtils"; import { Cursor, Utils } from "../Utils/Common"; import { MouseCommandType } from "./MouseCommandType"; import { MobileTextEditor } from "@aurigma/design-atoms-text/TextEditor/MobileTextEditor"; import { UpdateTextTriggerType } from "./UpdateTextTriggerType"; import { TextWhizzInitData } from "./TextWhizzInitData"; import { InputType, InputState } from "./../Input/InputManager/IInputManager"; import { Deferred } from "../Utils/Deferred"; import { ArgumentNullException } from "@aurigma/design-atoms-model"; //TODO: // 1) Split controllers for mobile and TextWhizz version. // 2) Remove dependency on Canvas and TextRenderer. /** * Manages a text editor (TextWhizz or mobile versions). * @remarks The text editor is shared by item handlers, we get it from 'Canvas' entry. The TextWhizz is used as a text engine. */ export class TextEditorController { get _textEditor() { return this._getTextEditor(); } constructor(itemHandler, _textWhizz, textRenderer, activeTextCanvasHandler, viewerConfig, fontRegistry, colorParser, textFormattingEnabled, getTextEditor) { this._textWhizz = _textWhizz; // events this._exitedEditModeEvent = new EventWithSenderArg(); this._enteredEditModeEvent = new EventWithSenderArg(); this._userZoomInProgress = false; this._waitUpdatePromise = null; this._onMobileTextEditorInitialized = () => { if (this._itemHandler === this._canvas.currentItemHandler) this.enterEditMode(0, 0); else this._canvas.redraw(); }; this._onSelectedItemHandlerChanged = async () => { if (this._textState === TextStateType.InEdit) await this.exitEditMode(); await this._setTextState(this.isOnlyThisItemSelected() ? TextStateType.Active : TextStateType.Static); }; this._onCanvasSelectionLocked = () => { if (this.isStatic) return; this._isTextImageValid = false; this._updateTextImage(); }; this._onTextStateChanged = async () => { if (!this.ready || this._userZoomInProgress) return; if (!(this.isStatic && this._isTextImageValid || this.isMobile && this.isInEdit)) { await this._updateText(UpdateTextTriggerType.Frame); } this._redrawText(); }; this._onCanvasScroll = () => { if (this._textState == TextStateType.InEdit) this._textEditor.processZoomChangedEvent(); }; this._onCanvasZoomChanged = async (args) => { this._userZoomInProgress = !args.fullUpdate; if (args.fullUpdate) { if (this._textState !== TextStateType.InEdit) { await this._setTextState(this.isOnlyThisItemSelected() ? TextStateType.Active : TextStateType.Static); } this._isTextImageValid = false; this._redrawText(); } if (this._textState == TextStateType.InEdit) this._textEditor.processZoomChangedEvent(); }; this._onFrameChanged = (frame) => { this.updateItemHandler(frame); }; this._onStyleChanged = () => { this.updateItemHandler(); this._canvas.redrawDesign(); this._canvas.updateSelection(); }; this._onInvalidInput = async () => { await this.exitEditMode(); }; if (_textWhizz == null) throw new ArgumentNullException("TextEditorController: textWhizz must not be null."); this._getTextEditor = getTextEditor; // dependencies this._itemHandler = itemHandler; this._canvas = this._itemHandler.canvas; this._textRenderer = textRenderer; this._colorParser = colorParser; this._viewerConfiguration = viewerConfig; this._textFormattingEnabled = textFormattingEnabled; this._activeTextCanvasHandler = activeTextCanvasHandler; this._listStyleSheetManagerFactory = new ListStyleSheetManagerFactory(Utils.getListSettingFromConfig(viewerConfig.listSettings)); this._listStyleSheetManager = this._listStyleSheetManagerFactory.create(); this._colorPreviewService = this._itemHandler.colorPreviewService; this._fontRegistry = fontRegistry; // text engine wrapper this._tw = this._createEngineWrapper(fontRegistry); // internal variables (default) this._textStateValue = this.isOnlyThisItemSelected() ? TextStateType.Active : TextStateType.Static; this._textImageChanged = new EventObject(); this._initialFormattedText = ''; this._isEnterToEditModeLocked = false; this._isExitFromEditModeLocked = false; this._mouseDownStartedInside = false; this._isTextImageValid = false; this._isDisposed = false; this._isCropped = null; this._ready = false; this._failed = false; } //#region - Status - get isMobile() { return this._textEditor instanceof MobileTextEditor; } get ready() { return this._ready; } get failed() { return this._failed; } get isStatic() { return this._textState === TextStateType.Static; } get isActive() { return this._textState === TextStateType.Active; } get isInEdit() { return this._textState === TextStateType.InEdit; } get isCropped() { if (this._isCropped == null) this._isCropped = this._tw.textMeasurer.isTextCropped(); return this._isCropped; } get enteredEditModeEvent() { return this._enteredEditModeEvent; } get exitedEditModeEvent() { return this._exitedEditModeEvent; } get activeTextEditor() { return this._textState === TextStateType.InEdit ? this._textEditor : null; } get canRedo() { return this._textEditor.canRedo; } get canUndo() { return this._textEditor.canUndo; } async waitUpdate() { if (this._ready) return; if (this._waitUpdatePromise != null) return this._waitUpdatePromise.promise; this._updateText(UpdateTextTriggerType.Initialization); if (this._waitUpdatePromise != null) return this._waitUpdatePromise.promise; } async initialize() { await this._initEngineWrapper(); } async enterEditMode(x, y) { if (!this._itemHandler.item.textPermissions.allowChangeText && !this._canvas.ignorePermissionsMode) return; if (!this._textEditor) return; if (this._textEditor.isActive || this._isEnterToEditModeLocked) { console.warn("TextEditorController: Cannot enter to edit mode when the editor is active"); return; } this._isEnterToEditModeLocked = true; const enterToEditMode = async (point) => { var _a; await this._setTextState(TextStateType.InEdit); this._initialFormattedText = !this._itemHandler.isEmptyTextPlaceholder() ? this._itemHandler.item.text : ''; if (this._itemHandler instanceof NewBoundedTextItemHandler && ((_a = this._itemHandler.item) === null || _a === void 0 ? void 0 : _a.overflowStrategy) == OverflowStrategy.ExpandBox) { this._initialBoundedRect = this._itemHandler.getTextRectangle().toRectangleF(); } await this._initEngineWrapper(this._initialFormattedText); await this._initActiveTextEditor(); this._bindToEditor(); this._textEditor.enterEditMode(point); this._setCanvasForEnterToEdit(); this._enteredEditModeEvent.notify(this); this._isEnterToEditModeLocked = false; }; const point = { x: x, y: y }; if (!this._itemHandler.item.transform.isEmpty) { await this._itemHandler.frontEndUpdate(); } await enterToEditMode(point); } async exitEditMode(isStayActive = false) { if (this._textEditor == null || this._isExitFromEditModeLocked) return; this._isExitFromEditModeLocked = true; const newText = await this._textEditor.getFormattedText(); this._textEditor.exitEditMode(); this._unbindFromEditor(); this._updateItemListStyles(); if (this._itemHandler.isEmptyTextPlaceholder()) this._restorePlaceholderText(); if (this._initialFormattedText !== newText) await this._handleTextChanged(newText); // state change should be after text change processing await this._setTextState(isStayActive ? TextStateType.Active : TextStateType.Static); this._setCanvasForExitFromEdit(); this._exitedEditModeEvent.notify(this); this._isExitFromEditModeLocked = false; } updateItemHandler(newFrame) { this._isCropped = null; const item = this._itemHandler.item; const itemHandler = this._itemHandler; const isPlainTextItem = itemHandler instanceof NewPlainTextItemHandler; const isCurvedTextItem = itemHandler instanceof NewCurvedTextItemHandler; const isArchedTextItem = itemHandler instanceof NewArchedTextItemHandler; const isBoundedTextItem = itemHandler instanceof NewBoundedTextItemHandler && item instanceof BoundedTextItem; const overflowStrategy = isBoundedTextItem ? item.overflowStrategy : null; if (isPlainTextItem || isCurvedTextItem || isArchedTextItem) { let handlerRect = newFrame; if (newFrame == null || newFrame.isEmpty()) { handlerRect = this.measureText(); } this._itemHandler.updateRectangle(handlerRect, true); this._tw.textHandler.setTextFrames(this._itemHandler.getFramesData(), false); this._canvas.redrawDesign(); } else if (isBoundedTextItem && overflowStrategy === OverflowStrategy.ExpandBox) { let frame = newFrame !== null && newFrame !== void 0 ? newFrame : this.measureTextFrame(true); if (frame && !frame.isEmpty()) { if (frame.height > this._initialBoundedRect.height) { const updateRect = this._initialBoundedRect.clone(); updateRect.height = frame.height + 1.5; this._itemHandler.updateRectangle(updateRect, true); } else { this._itemHandler.updateRectangle(this._initialBoundedRect, true); } } this._tw.textHandler.setTextFrames(this._itemHandler.getFramesData(), false); this._canvas.redrawDesign(); this._canvas.updateSelection(); this._itemHandler.raiseChanged(); } else this._itemHandler.raiseChanged(); } bindToCanvas(canvas) { if (canvas == null) return; this._canvas = canvas; this._canvas.add_onScroll(this._onCanvasScroll); this._canvas.add_zoomChanged(this._onCanvasZoomChanged); this._canvas.add_selectedItemHandlerChanged(this._onSelectedItemHandlerChanged); this._canvas.add_onSelectionLocked(this._onCanvasSelectionLocked); } unbindFromCanvas() { var _a, _b, _c, _d; (_a = this._canvas) === null || _a === void 0 ? void 0 : _a.remove_onScroll(this._onCanvasScroll); (_b = this._canvas) === null || _b === void 0 ? void 0 : _b.remove_zoomChanged(this._onCanvasZoomChanged); (_c = this._canvas) === null || _c === void 0 ? void 0 : _c.remove_selectedItemHandlerChanged(this._onSelectedItemHandlerChanged); (_d = this._canvas) === null || _d === void 0 ? void 0 : _d.remove_onSelectionLocked(this._onCanvasSelectionLocked); this._canvas = null; } add_staticTextImageChanged(handler) { this._textImageChanged.add(handler); } remove_staticTextImageChanged(handler) { this._textImageChanged.remove(handler); } dispose() { this.clearText(); this.unbindFromCanvas(); this._isDisposed = true; } async processKeyEvent(e) { if (e.code === Keys.Escape) { await this.exitEditMode(true); return true; } else return await this._textEditor.processKeyEvent(e); } async processMouseEvent(pointerParams, mouseOverCurrent) { const event = this._getMouseEvent(pointerParams); this._updateMouseDownStartedInside(event.type, mouseOverCurrent); const commandType = this._getMouseCommandType(event, mouseOverCurrent); switch (commandType) { case MouseCommandType.noProcessingRequired: { return false; } case MouseCommandType.toProcessInEditMode: { if (!this.isMobile) this._textEditor.processMouseEvent(event); break; } case MouseCommandType.enterToEditMode: { if (this._viewerConfiguration.rotatedTextInPlaceEditEnabled === false && ItemUtils.isRotated(this._itemHandler.item, this._canvas.contentAngle)) { return false; } if (this.isMobile && !this._textEditor.isReady) { this._textEditor.editorInitialized.remove(this._onMobileTextEditorInitialized); this._textEditor.editorInitialized.add(this._onMobileTextEditorInitialized); this._canvas.redraw(); return false; } await this.enterEditMode(event.x, event.y); break; } case MouseCommandType.exitFromEditMode: { await this.exitEditMode(); return false; } case MouseCommandType.outsideSelection: { this._canvas.enableSelection(); return false; } } this._defineCanvasCursor(mouseOverCurrent); return true; } clearText() { // clean } async updateText(trigger, force = false) { await this._updateText(this._getUpdateTextTrigger(trigger), force); } transformText(transform) { var _a; const item = this._itemHandler.item; const center = this._itemHandler.getControlCenter(); const previewScale = item.previewScale; const opacity = item.opacity; const clippingPath = (_a = item.mask) === null || _a === void 0 ? void 0 : _a.vectorMask; const engineHandler = this._tw.engineHandler; this._textRenderer.transformText(engineHandler, transform, center, previewScale, opacity, clippingPath); } measureText(extendToBlackBox) { const previewScale = this._itemHandler.item.previewScale; return this._tw.textMeasurer.measureText(previewScale, extendToBlackBox); } measureTextFrame(useActiveText = false) { return this._tw.textMeasurer.measureTextFrames(useActiveText); } redrawActiveText() { var _a; if (this._isDisposed) return; if (this._textState !== TextStateType.Active && this._textState !== TextStateType.InEdit) return; const item = this._itemHandler.item; const useOpacityMultiplier = !this.isInEdit; const opacityMultiplier = useOpacityMultiplier && this._itemHandler.isEmptyTextPlaceholder() ? 0.5 : 1; const opacity = item.opacity * opacityMultiplier; const textEngineHandler = this._tw.engineHandler; const transform = item.transform; const center = this._itemHandler.getControlCenter(); const previewScale = item.previewScale; const clippingPath = this._textState !== TextStateType.InEdit ? (_a = item.mask) === null || _a === void 0 ? void 0 : _a.vectorMask : null; this._textRenderer.drawText(textEngineHandler, transform, center, previewScale, opacity, clippingPath); if (this._textState === TextStateType.InEdit) this._textEditor.redraw(); } undo() { this._textEditor.undo(); } redo() { this._textEditor.redo(); } _createEngineWrapper(fontRegistry) { return new TextWhizzWrapper(this._textWhizz, fontRegistry.textWhizzFontRegistry, this._listStyleSheetManager, this._colorPreviewService, this._colorParser); } async _getEngineWrapperInitData(text = null) { const initData = new TextWhizzInitData(this._itemHandler, this._colorPreviewService); await initData.update(text); return initData; } async _initEngineWrapper(text = null) { const missingFonts = this._getMissingFonts(); if (missingFonts.length > 0) { await this._fontRegistry.loadFonts(missingFonts); } this._listStyleSheetManager.initialize(this._parseItemListStyles(this._itemHandler.item)); this._tw.initialize(await this._getEngineWrapperInitData(text)); } _getTextWhizzEditorInitData() { const item = this._itemHandler.item; const itemHandler = this._itemHandler; const isBoundedTextItem = itemHandler instanceof NewBoundedTextItemHandler && item instanceof BoundedTextItem; const overflowStrategy = isBoundedTextItem ? item.overflowStrategy : null; const textVerticalAlignment = isBoundedTextItem ? item.verticalAlignment : null; const textFormattingEnabled = ItemUtils.getAllowTextFormatting(item, this._textFormattingEnabled); const isEmptyTextPlaceholder = itemHandler.isEmptyTextPlaceholder(); const isSingleLineText = item instanceof ArchedTextItem || item instanceof CurvedTextItem; return { rectangle: itemHandler.rectangle.toRectangleF(), previewScale: item.previewScale, textVerticalAlignment: textVerticalAlignment, overflowStrategy: overflowStrategy, isBoundedText: isBoundedTextItem, isTextFormattingEnabled: textFormattingEnabled, isNewLineEnabled: !(item instanceof CurvedTextItem || item instanceof ArchedTextItem), isEmptyTextPlaceholder: isEmptyTextPlaceholder, limits: { characterLimit: item.characterLimit, maxLineCount: item.maxLineCount, maxLineLength: item.maxLineLength, isSingleLineText: isSingleLineText } }; } async _getMobileEditorInitData() { const item = this._itemHandler.item; let alignment = null; if (item instanceof PlainTextItem || item instanceof CurvedTextItem) alignment = item.alignment; if (item instanceof ArchedTextItem) alignment = TextAlignment.Center; let isVertical = false; if (item instanceof PlainTextItem || item instanceof BoundedTextItem || item instanceof PathBoundedTextItem) isVertical = item.isVertical; const borderColorPreview = await this._colorPreviewService.getPreviewAsync(item.borderColor); const fillColorPreview = await this._colorPreviewService.getPreviewAsync(item.fillColor); const isSingleLineText = item instanceof ArchedTextItem || item instanceof CurvedTextItem; const rectangle = this._itemHandler.rectangle.clone(); if (item instanceof ArchedTextItem || item instanceof CurvedTextItem) { rectangle.translate(0, rectangle.height / 2); rectangle.angle = 0; } return { text: this._initialFormattedText, rectangle: rectangle, textAlignment: alignment, defaultInlineStyle: await TextWhizzInitData.getDefaultInlineStyle(item, this._colorPreviewService), defaultParagraphStyle: TextWhizzInitData.getDefaultParagraphStyle(item), borderColor: borderColorPreview.toString(), borderWidth: item.borderWidth, fillColor: fillColorPreview.toString(), opacity: item.opacity, previewScale: item.previewScale, textFormattingEnabled: ItemUtils.getAllowTextFormatting(item, this._textFormattingEnabled), transform: item.transform, textVerticalAlignment: item instanceof BoundedTextItem ? item.verticalAlignment : null, listSettings: Object.assign({}, this._viewerConfiguration.listSettings), limits: { characterLimit: item.characterLimit, maxLineCount: item.maxLineCount, maxLineLength: item.maxLineLength, isSingleLineText: isSingleLineText }, isVertical: isVertical }; } async _initActiveTextEditor() { //TODO: add call _initEngineWrapper() if (this.activeTextEditor) { const editorInitData = this._getTextWhizzEditorInitData(); if (this._textEditor instanceof NewTextEditor) { this._textEditor.renderer.initialize(this._itemHandler); this._textEditor.initialize(this._tw, editorInitData, this._listStyleSheetManager); } else if (this._textEditor instanceof MobileTextEditor) { let initData = await this._getMobileEditorInitData(); let colorPalette = this._tw.colorPalette; this._textEditor.initialize(initData, colorPalette, this._listStyleSheetManager); } } } _bindToEditor() { this._textEditor.frameChanged.add(this._onFrameChanged); this._textEditor.styleChanged.add(this._onStyleChanged); this._textEditor.invalidCharEntered.add(this._onInvalidInput); } _unbindFromEditor() { this._textEditor.frameChanged.remove(this._onFrameChanged); this._textEditor.styleChanged.remove(this._onStyleChanged); this._textEditor.invalidCharEntered.remove(this._onInvalidInput); } redrawText() { this._redrawText(); } _getMissingFonts() { const itemFonts = this._itemHandler.getFonts(); return itemFonts.filter(font => !this._fontRegistry.containsFonts([font])); } _updateMouseDownStartedInside(eventType, mouseOverCurrent) { if (this._textState !== TextStateType.InEdit) return; if (eventType === MouseEventType.mousedown) this._mouseDownStartedInside = mouseOverCurrent; if (eventType === MouseEventType.mouseup) this._mouseDownStartedInside = false; } _getMouseCommandType(e, mouseOverCurrent) { const isEditState = this._textState === TextStateType.InEdit; switch (e.type) { case MouseEventType.dblclick: { if (!isEditState) return MouseCommandType.enterToEditMode; else return mouseOverCurrent ? MouseCommandType.toProcessInEditMode : MouseCommandType.exitFromEditMode; } case MouseEventType.mousedown: { if (!isEditState) return MouseCommandType.noProcessingRequired; else return mouseOverCurrent ? MouseCommandType.toProcessInEditMode : MouseCommandType.noProcessingRequired; } case MouseEventType.mousemove: { if (!isEditState) return MouseCommandType.noProcessingRequired; else { const isExitFromEditMode = !mouseOverCurrent && e.isDrag && !this._mouseDownStartedInside && !Environment.IsTouchDevice(); return isExitFromEditMode ? MouseCommandType.exitFromEditMode : MouseCommandType.toProcessInEditMode; } } case MouseEventType.mouseup: { if (!isEditState) { return this.isOnlyThisItemSelected() ? MouseCommandType.enterToEditMode : MouseCommandType.noProcessingRequired; } else return !mouseOverCurrent && e.isClick ? MouseCommandType.exitFromEditMode : MouseCommandType.toProcessInEditMode; } } } _getMouseEvent(e) { let type = null; const isMove = e.type === InputType.Move; const state = isMove ? e.state : null; if (e.type === InputType.PointerDown) type = MouseEventType.mousedown; if (e.type === InputType.Hover || (isMove && state === InputState.InProgress || state === InputState.Started)) type = MouseEventType.mousemove; if (e.type === InputType.Click || (isMove && state === InputState.Finished)) type = MouseEventType.mouseup; const point = this._translatePoint(new PointF(e.workspace.x, e.workspace.y)); return { x: point.x, y: point.y, type: type, isClick: e.type === InputType.Click, isDrag: e.type === InputType.Move, clickCount: e.clickCount, }; } _translatePoint(point) { const offset = this._canvas.offset; const transform = this._itemHandler.item.transform; const previewScale = this._itemHandler.item.previewScale; const rectangle = this._itemHandler.rectangle.toRectangleF(); point.translate(-offset.x, -offset.y); if (transform != null) { point.rotateAt(-transform.angle, rectangle.center); point.translate(-transform.translateX, -transform.translateY); } point.scale(1 / previewScale, 1 / previewScale); return point; } get _textState() { return this._textStateValue; } async _setTextState(value) { if (this._textStateValue === value) return; this._textStateValue = value; await this._onTextStateChanged(); } _redrawText() { var _a; if (this._textState === TextStateType.Static) { if (!this._isTextImageValid) { this._updateTextImage(); } } (_a = this._canvas) === null || _a === void 0 ? void 0 : _a.redrawActiveTexts(); } _updateTextImage() { this._itemHandler.clearImageContainer(); const previewScale = this._itemHandler.item.previewScale; const textRectangle = this._tw.textMeasurer.measureText(previewScale, true); const textEngineHandler = this._tw.engineHandler; const textImageCanvas = this._textRenderer.getTextImage(textEngineHandler, textRectangle, previewScale); this._textImageChanged.fire({ rect: textRectangle, canvas: textImageCanvas }); this._isTextImageValid = true; } async _updateText(trigger, force = false) { if (this._isDisposed) return; const toCheckTextChanged = !this.isMobile && trigger === UpdateTextTriggerType.Text && !force; if (toCheckTextChanged) { const itemText = this._itemHandler.item.text; const currentText = this._tw.textHandler.getFormattedText(); const isTextActual = itemText === currentText; if (isTextActual) return; } if (this._waitUpdatePromise != null) return this._waitUpdatePromise.promise; const waitUpdatePromise = new Deferred(); this._waitUpdatePromise = waitUpdatePromise; this._ready = false; try { if (this._textState === TextStateType.Static) { this._itemHandler.clearImageContainer(); } try { if (trigger === UpdateTextTriggerType.Initialization || trigger === UpdateTextTriggerType.Text) { await this._initEngineWrapper(); await this._initActiveTextEditor(); } if (trigger === UpdateTextTriggerType.Frame) { await this._initEngineWrapper(); // Currently there's no guarantee that this method is properly awaited // so unexpected dispose can occur during method execution if (this._isDisposed) return; const framesData = this._itemHandler.getFramesData(); this._tw.textHandler.setTextFrames(framesData, false); } if (trigger === UpdateTextTriggerType.WrappingPath) { const wrappingPathData = this._itemHandler.getWrappingPathData(); this._tw.textHandler.setWrappingPath(wrappingPathData); } } catch (e) { this._failed = true; throw TextWhizzWrapper.createException(this._tw.engine, e); } // Same as the above if (this._isDisposed) return; this._ready = true; this._failed = false; this._isCropped = null; this._isTextImageValid = false; const previewScale = this._itemHandler.item.previewScale; const textRectangle = this._tw.textMeasurer.measureText(previewScale, false); const updateFromTextEdit = trigger === UpdateTextTriggerType.Text; this._itemHandler.updateRectangle(textRectangle, updateFromTextEdit); this._redrawText(); // if (this.isMobile) { // if (this._textState === TextStateType.InEdit && !this._isExitFromEditModeLocked) { // await this.exitEditMode(); // await this.enterEditMode(0, 0); // } // } } finally { this._waitUpdatePromise = null; waitUpdatePromise.resolve(); } } _getUpdateTextTrigger(trigger) { if (trigger == null) return UpdateTextTriggerType.Initialization; if (trigger.toLowerCase() === 'text') return UpdateTextTriggerType.Text; if (trigger.toLowerCase() === 'frame') return UpdateTextTriggerType.Frame; if (trigger.toLowerCase() === 'wrappingpath') return UpdateTextTriggerType.WrappingPath; return null; } _restorePlaceholderText() { this._tw.textHandler.insertFormattedText(this._itemHandler.item.originalText); this.updateItemHandler(); } _updateItemListStyles() { const listStyleSheets = this._listStyleSheetManager.getAllStyleSheets().map(x => x.getListStyleSheet()); this._itemHandler.item.listStyles = this._serializeToItemListStyles(listStyleSheets); } async _handleTextChanged(newText) { this._isTextImageValid = false; const extractResult = this._extractDefaultTextStyle(newText); this._itemHandler.item.text = extractResult.text; this._itemHandler.applyInlineStyle(this._convertFromModelSpanStyle(extractResult.spanStyle)); this._itemHandler.applyParagraphStyle(this._convertFromModelParagraphStyle(extractResult.paragraphStyle)); if (!this.isMobile && this._itemHandler.item) //TODO: to del after support RTL text in TextWhizz await this._initEngineWrapper(); } _extractDefaultTextStyle(formattedText) { const colors = this._tw.colorPalette.getPaletteColors(); const colorPalette = new ColorPalette(colors); const converter = new DefaultStyleExtractor(this._colorParser); const defaultFontSize = this._tw.styleHandler.getDefaultCharStyle().font.size; return converter.extract(formattedText, colorPalette, defaultFontSize, this._listStyleSheetManager); } _defineCanvasCursor(mouseOverCurrent) { const cursor = mouseOverCurrent ? Cursor.text : Cursor.defaultCursor; this._canvas.setCursor(cursor, false); } _setCanvasForExitFromEdit() { this._canvas.unsubscribeLimitsMessage(); this._activeTextCanvasHandler.moveActiveTextCanvasBack(); this._canvas.enableSelection(); this._canvas.redraw(); } _setCanvasForEnterToEdit() { this._canvas.subscribeLimitsMessage(); this._activeTextCanvasHandler.moveActiveTextCanvasOnTop(); this._canvas.disableSelection(); this._canvas.ensureFocus(); this._canvas.redraw(); } isOnlyThisItemSelected() { var _a, _b; return (_b = (_a = this._canvas) === null || _a === void 0 ? void 0 : _a.isOnlyThisItemHandlerSelected(this._itemHandler)) !== null && _b !== void 0 ? _b : false; } _serializeToItemListStyles(listStyleSheets) { return (listStyleSheets === null || listStyleSheets === void 0 ? void 0 : listStyleSheets.length) > 0 ? JSON.stringify(listStyleSheets) : ''; } _parseItemListStyles(item) { return item.listStyles ? JSON.parse(item.listStyles) : []; } _convertFromModelSpanStyle(source) { var _a, _b, _c, _d, _e; let font = null; const hasFontSettings = source.fontName || source.fontSize || source.bold !== undefined || source.italic !== undefined || source.allCaps !== undefined; if (hasFontSettings) { font = { postScriptName: source.fontName, size: (_a = source.fontSize) === null || _a === void 0 ? void 0 : _a.value, fauxBold: source.bold, fauxItalic: source.italic, allCaps: source.allCaps }; } let stroke = null; if (source.penColor || source.penWidth) { stroke = { color: (_b = source.penColor) === null || _b === void 0 ? void 0 : _b.color, size: (_c = source.penWidth) === null || _c === void 0 ? void 0 : _c.value }; } return { font: font, color: (_d = source.color) === null || _d === void 0 ? void 0 : _d.color, underline: source.underline, leading: (_e = source.leading) === null || _e === void 0 ? void 0 : _e.value, tracking: source.tracking, stroke: stroke, openType: source.openTypeFeatures, subscript: source.sub, superscript: source.sup, verticalScale: source.verticalScale, horizontalScale: source.horizontalScale }; } _convertFromModelParagraphStyle(value) { var _a, _b, _c, _d, _e; return { alignment: this._convertToModelParagraphAlignment(value.alignment), firstLineIndent: (_a = value.firstLineIndent) === null || _a === void 0 ? void 0 : _a.value, spaceBefore: (_b = value.spaceBefore) === null || _b === void 0 ? void 0 : _b.value, spaceAfter: (_c = value.spaceAfter) === null || _c === void 0 ? void 0 : _c.value, leftIndent: (_d = value.leftIndent) === null || _d === void 0 ? void 0 : _d.value, rightIndent: (_e = value.rightIndent) === null || _e === void 0 ? void 0 : _e.value }; } _convertToModelParagraphAlignment(source) { switch (source) { case ParagraphAlignment.left: return TextAlignment.Left; case ParagraphAlignment.center: return TextAlignment.Center; case ParagraphAlignment.right: return TextAlignment.Right; case ParagraphAlignment.justification: return TextAlignment.Justify; case ParagraphAlignment.lastLeft: return TextAlignment.LastLeft; case ParagraphAlignment.lastCenter: return TextAlignment.LastCenter; case ParagraphAlignment.lastRight: return TextAlignment.LastRight; } } } //# sourceMappingURL=TextEditorController.js.map