@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
JavaScript
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