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.

585 lines 25.8 kB
import { RectangleF, PointF, Path, RotatedRectangleF, Transform } from "@aurigma/design-atoms-model/Math"; import { StrokeSettings } from "@aurigma/design-atoms-model/Product/Items"; import * as Utils from "@aurigma/design-atoms-model/Utils/Utils"; import { MobileTextEditor } from "@aurigma/design-atoms-text/TextEditor/MobileTextEditor"; import { Graphics } from "../Graphics"; import { TextRenderer } from "../InPlace/TextRenderer"; import { Deferred } from "../Utils/Deferred"; import { ImageContainer } from "./ImageContainer"; import { ShapeItemHandler } from "./ShapeItemHandler"; import { NotImplementedException, Exception } from "@aurigma/design-atoms-model/Exception"; import { EventWithSenderArg } from "@aurigma/design-atoms-model/EventObject"; import { applyIfDefined } from "../Utils/Functions"; import { toTextWhizzPath } from "@aurigma/design-atoms-text/Utils/PathUtils"; import { InputState } from "./../Input/InputManager/IInputManager"; import { AsyncHelper } from "../Utils/AsyncHelper"; import { ItemHandlerState } from "./ItemHandlerState"; import { TextUtils } from "@aurigma/design-atoms-text/Utils"; export class NewBaseTextItemHandler extends ShapeItemHandler { constructor(fontRegistry, textEditorControllerFactory, item, textWhizz = null, apiClient, colorPreviewService, colorParser) { super(null, item, textWhizz, apiClient, colorPreviewService); this._fontRegistryUpdated = null; this._waitLoadFontsDef = null; this._waitLoadFontsLastInnerUpdate = null; this._frontEndUpdateExecutionToken = AsyncHelper.getExecutionToken(); this._initFrontEndRenderingDef = null; this._staticTextRect = null; this._exitedEditModeEvent = new EventWithSenderArg(); this._enteredEditModeEvent = new EventWithSenderArg(); this._onStaticTextImageChanged = (data) => { var _a; if (data.canvas == null) { this._imageContainer.clear(); (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.redraw(); } else { this._staticTextRect = data.rect; this._imageContainer.updateCanvas(data.canvas); } }; this._fontRegistry = fontRegistry; this._textEditorControllerFactory = textEditorControllerFactory; this._colorParser = colorParser; let rectangle = this.item != null ? this.item.sourceRectangle : null; if (rectangle == null || rectangle.isEmpty()) rectangle = new RectangleF(0, 0, 10, 10); this.originalPath = Path.rectangle(rectangle.left, rectangle.top, rectangle.width, rectangle.height); this.controlPoints = [new PointF(rectangle.left, rectangle.top), new PointF(rectangle.right, rectangle.bottom)]; this._imageContainer = new ImageContainer(async () => { var _a, _b; try { if (this.canvas == null) return; (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.redraw(); await this.waitUpdate(); (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.redraw(); } catch (ex) { console.warn(`Error in [NewBaseTextItemHandler].ctor ImageContainer loaded`, ex); throw ex; } }); this._allowNegativeResize = false; } isHighlightNeeded() { return this.editing; } get textEditorController() { return this._textEditorController; } get item() { return this._getItem(); } set item(item) { super._setItem(item); } get isInEdit() { var _a; return (_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.isInEdit; } get textEditor() { var _a; return (_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.activeTextEditor; } get editing() { return this.textEditor != null; } get textCropped() { if (!this.item.checkTextCrop) return null; if (this.ready && this.frontEndRenderingReady) return this._textEditorController.isCropped; else return false; } get frontEndRenderingReady() { const textWhizzReady = this._textWhizz != null; const textManagerReady = this._textEditorController != null && !this._textEditorController.failed; const fontsReady = this._fontRegistry != null && this._fontRegistry.ready && this._fontRegistry.containsFonts(this.getFonts()); return textWhizzReady && textManagerReady && fontsReady; } get inPlaceEditingEnabled() { return this.frontEndRenderingReady && this.item.placeholders.length == 0; } get exitedEditModeEvent() { return this._exitedEditModeEvent; } get enteredEditModeEvent() { return this._enteredEditModeEvent; } get colorPreviewService() { return this._colorPreviewService; } updateText(text) { this._modifyItem((i) => { i.text = text; }); } applyInlineStyle(style) { if (!style) return; applyIfDefined(style.color, value => this.item.color = value); applyIfDefined(style.font, value => { applyIfDefined(value.postScriptName, v => this.item.font.postScriptName = v); applyIfDefined(value.allCaps, v => this.item.font.allCaps = v); applyIfDefined(value.fauxBold, v => this.item.font.fauxBold = v); applyIfDefined(value.fauxItalic, v => this.item.font.fauxItalic = v); applyIfDefined(value.size, v => this.item.font.size = v); }); applyIfDefined(style.leading, value => this.item.leading = value); applyIfDefined(style.openType, value => this.item.font.openTypeFeatures = value); applyIfDefined(style.stroke, value => { if (this.item.stroke == null) this.item.stroke = new StrokeSettings(); applyIfDefined(value.color, value => this.item.stroke.color = value); applyIfDefined(value.size, value => this.item.stroke.size = value); }); applyIfDefined(style.tracking, value => this.item.tracking = value); applyIfDefined(style.underline, value => this.item.underline = value); } applyParagraphStyle(paragraphStyle) { applyIfDefined(paragraphStyle.alignment, v => this.item.alignment = v); } isEmpty() { var _a; return this.item.isEmpty() && !((_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.isInEdit); } isEmptyTextPlaceholder() { return this.item.isTextPlaceholder && TextUtils.isTextEmpty(this.item.text); } setTextWhizzModule(textWhizz, fontRegistry) { this._textWhizz = textWhizz; this._fontRegistry = fontRegistry; if (this._fontRegistryUpdated != null) this._fontRegistryUpdated.resolve(); } onTextWhizzInit() { super.onTextWhizzInit(); this.update(); } async waitUpdate() { if (this._isDisposed) return; const promisesToWait = []; if (!this.frontEndRenderingReady) { promisesToWait.push(this.waitInitFrontEndRendering()); this.update(); } if (this.textEditorController) promisesToWait.push(this.textEditorController.waitUpdate()); promisesToWait.push(super.waitUpdate()); await Promise.all(promisesToWait); } async frontEndUpdate(beforeUpdate, afterUpdate, trigger) { if (this._isDisposed) return; if (this._fontRegistry == null && this.canvas == null) return; if (this._handlerUpdated == null) this._handlerUpdated = new Deferred(); if (!this._isFrontEndRenderingInitialized()) { await AsyncHelper.executeSingle(this._frontEndUpdateExecutionToken, async () => { await this.waitInitFrontEndRendering(); }, async () => { await this._doFrontEndUpdate(beforeUpdate, afterUpdate, trigger); }); } else { await this._doFrontEndUpdate(beforeUpdate, afterUpdate, trigger); } } update(beforeUpdate, afterUpdate, trigger) { this._updateImpl(beforeUpdate, afterUpdate, trigger); } async updateAsync(beforeUpdate, afterUpdate, trigger) { await this._updateImpl(beforeUpdate, afterUpdate, trigger); } quickUpdate() { if (this.isVisible() && this.canvas && !this.frontEndRenderingReady) { this.update(); } } setRectangle(rectangle, supressOnChanged) { var _a; const controlBounds = RotatedRectangleF.fromRectangleF(this.getControlBounds()); const transform = rectangle.getTransform(controlBounds); if (!transform.equals(this.item.transform)) { this.item.setTransform(transform, supressOnChanged); if ((_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.isActive) { this._transformText(transform); } } } updateRectangle(rectangle, updateFromTextEdit) { let changed = false; this._modifyItem((i) => { changed = !RectangleF.isEqual(i.sourceRectangle, rectangle); if (changed) { i.sourceRectangle = rectangle; i.sourcePath = Path.rectangle(rectangle.left, rectangle.top, rectangle.width, rectangle.height); } }); if (this.controlPoints == null || this.controlPoints.length == 0) { changed = true; } else { const cp0 = this.controlPoints[0]; const cp1 = this.controlPoints[1]; const oldRect = RectangleF.FromLTRB(cp0.x, cp0.y, cp1.x, cp1.y); if (!oldRect.equals(rectangle)) { changed = true; } } if (changed) { this.controlPoints = [new PointF(rectangle.left, rectangle.top), new PointF(rectangle.right, rectangle.bottom)]; this.item.getItemChangedEvent().fire(); } } redrawActiveText() { if (this.canvas == null || this._textEditorController == null) return; this._textEditorController.redrawActiveText(); } drawItemHandler(itemHandlerCtx) { var _a, _b; if (itemHandlerCtx == null || this.canvas == null || this._textWhizz == null) return; if (!this._isReadyToDraw) { this.canvas.drawWaitClock(itemHandlerCtx, this.rectangle.center); return; } const renderForEyeDropper = this.ready && !((_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.isStatic) && this.canvas.isSelectionLocked; if (this._hasVectorMask() && !renderForEyeDropper) { itemHandlerCtx.save(); this._clip(itemHandlerCtx); } if (!this._isMobileTextEditorActive || renderForEyeDropper) { const opacityMultiplier = this.isEmptyTextPlaceholder() ? 0.5 : 1; this.renderFill(itemHandlerCtx, opacityMultiplier); if (!this.ready || ((_b = this._textEditorController) === null || _b === void 0 ? void 0 : _b.isStatic) || renderForEyeDropper) { try { TextRenderer.renderTextImage(this, this._imageContainer, null, itemHandlerCtx, opacityMultiplier, TextRenderer.staticCanvasMargin); } catch (e) { console.error(e); } } this.renderStroke(itemHandlerCtx, opacityMultiplier); } if (this._hasVectorMask() && !renderForEyeDropper) itemHandlerCtx.restore(); this._drawHandlerEffects(itemHandlerCtx); } clearImageContainer() { this._imageContainer.clear(); } _endTransform(changed, resized) { super._endTransform(changed, resized); if (!changed || !resized || !this.frontEndRenderingReady) return; this.update(null, null, this._getEndTransformTrigger(resized)); } async processInPlaceEditingMouseEvent(e, mouseOverCurrent) { if (!this.inPlaceEditingEnabled) throw new Exception(`Inplace is not enabled for this item!`); return await this._textEditorController.processMouseEvent(e, mouseOverCurrent); } async processInPlaceEditingKeyEvent(e) { if (!this.inPlaceEditingEnabled) throw new Exception(`Inplace is not enabled for this item!`); e.preventDefault(); if (e.state !== InputState.Finished) return await this._textEditorController.processKeyEvent(e); return true; } enterEditMode() { if (!this.inPlaceEditingEnabled) throw new Exception(`Inplace is not enabled for this item!`); return this._textEditorController.enterEditMode(0, 0); } exitEditMode(stayActive = false) { if (!this.inPlaceEditingEnabled) throw new Exception(`Inplace is not enabled for this item!`); return this._textEditorController.exitEditMode(stayActive); } getTextForRendering() { return this.isEmptyTextPlaceholder() ? this.item.originalText : this.item.text; } dispose() { var _a, _b, _c; (_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.exitedEditModeEvent.remove(this._onTextManagerExitedEditMode); (_b = this._textEditorController) === null || _b === void 0 ? void 0 : _b.enteredEditModeEvent.remove(this._onTextManagerEnteredEditMode); (_c = this._textEditorController) === null || _c === void 0 ? void 0 : _c.dispose(); this._textEditorController = null; this._imageContainer.dispose(); super.dispose(); } getFonts() { return [ this.item.font.postScriptName, ...Utils.getFontNames(this.item.text), ...Utils.getFontNames(this.item.originalText), ]; } _isReady() { var _a; return super._isReady() && ((_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.ready); } _drawHandlerEffects(ctx) { } _getColors() { var _a; return [this.item.color, ...(_a = this.item.colorPalette) === null || _a === void 0 ? void 0 : _a.toArray(), ...super._getColors()]; } async _updateImpl(beforeUpdate, afterUpdate, trigger) { if (this.isVisible() || trigger == "text") { const postUpdate = () => { var _a, _b; if (typeof afterUpdate == "function") afterUpdate(); (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.updateSelection(true); (_b = this.canvas) === null || _b === void 0 ? void 0 : _b.redrawDesign(); }; await this.frontEndUpdate(beforeUpdate, postUpdate, trigger); } else if (typeof beforeUpdate == "function") { beforeUpdate(); } } _onItemPropertyChanged(sender, propertyName) { var _a; switch (propertyName) { case "text": (_a = this.textEditorController) === null || _a === void 0 ? void 0 : _a.initialize(); this.update(null, null, "text"); break; case "font": case "underline": case "color": case "alignment": case "leading": case "tracking": case "verticalScale": case "horizontalScale": case "previewScale": case "stroke": case "shadow": case "baselineShift": case "overlapLinesEnabled": case "maxLineCount": case "maxLineLength": this.update(); break; case "checkTextCrop": if (!this.frontEndRenderingReady && sender.checkTextCrop) this.update(); break; default: } if (propertyName !== "checkTextCrop") super._onItemPropertyChanged(sender, propertyName); } _onItemVisibilityChanged() { var _a, _b, _c; super._onItemVisibilityChanged(); if ((_a = this.canvas) === null || _a === void 0 ? void 0 : _a.isItemHandlerSelected(this)) { if (this.isVisible()) (_b = this._textEditorController) === null || _b === void 0 ? void 0 : _b.updateItemHandler(); else (_c = this._textEditorController) === null || _c === void 0 ? void 0 : _c.clearText(); } } _setDataItem(itemData, itemHandlerData) { throw new NotImplementedException("NewBaseTextItemHandler._setDataItem"); } _createDataInstance(itemHandler) { throw new NotImplementedException("NewBaseTextItemHandler._createDataInstance"); } _onAddedOnCanvas(canvas) { var _a; this._textWhizz = canvas.textWhizz; super._onAddedOnCanvas(canvas); (_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.bindToCanvas(canvas); } _onRemovedFromCanvas(canvas) { var _a; super._onRemovedFromCanvas(canvas); (_a = this._textEditorController) === null || _a === void 0 ? void 0 : _a.unbindFromCanvas(); } _transformText(transform) { this._textEditorController.transformText(transform); } _getBoundsMargin() { return this._getActualBorderWidth() * 2; } renderFill(itemHandlerCtx, opacityMultiplier) { const item = this.item; const rectangle = this.rectangle; const { fillColorPreview } = this._getItemColorPreviews(); Graphics.fillRectangle(itemHandlerCtx, rectangle, fillColorPreview === null || fillColorPreview === void 0 ? void 0 : fillColorPreview.toString(), item.opacity * opacityMultiplier); } renderStroke(itemHandlerCtx, opacityMultiplier) { const borderWidth = this._getActualBorderWidth(); if (borderWidth <= 0) return; const item = this.item; const rectangle = this.rectangle; rectangle.width += borderWidth; rectangle.height += borderWidth; const path = Path.rotatedRectangle(rectangle); const { borderColorPreview, altBorderColorPreview } = this._getItemColorPreviews(); Graphics.drawStroke(itemHandlerCtx, path, rectangle.center, new Transform(), borderWidth, borderColorPreview.toString(), altBorderColorPreview === null || altBorderColorPreview === void 0 ? void 0 : altBorderColorPreview.toString(), item.opacity * opacityMultiplier, item.dash); } _getEndTransformTrigger(resized) { return "frame"; } _onFrontEndRenderingInitialized() { } async _initFrontEndRendering() { this._textEditorController = this._textEditorControllerFactory.create(this, this._textWhizz); await this._textEditorController.initialize(); this._textEditorController.add_staticTextImageChanged(this._onStaticTextImageChanged); this._textEditorController.exitedEditModeEvent.add(this._onTextManagerExitedEditMode.bind(this)); this._textEditorController.enteredEditModeEvent.add(this._onTextManagerEnteredEditMode.bind(this)); this._textEditorController.bindToCanvas(this.canvas); this._onFrontEndRenderingInitialized(); } _onTextManagerEnteredEditMode() { this._enteredEditModeEvent.notify(this); this.canvas.redrawActiveTexts(); } _onTextManagerExitedEditMode() { this._exitedEditModeEvent.notify(this); } _getPreviewScaleLimits() { let maxPreviewScale = null; let minPreviewScale = null; if (this.canvas != null && this.canvas.maxFontSize != null && !isNaN(this.canvas.maxFontSize)) maxPreviewScale = this.canvas.maxFontSize / this.item.font.size; if (this.canvas != null && this.canvas.minFontSize != null && !isNaN(this.canvas.minFontSize)) minPreviewScale = this.canvas.minFontSize / this.item.font.size; return { min: minPreviewScale, max: maxPreviewScale }; } async waitInitFrontEndRendering() { if (this._fontRegistry != null && this._textEditorController != null) return; if (this._initFrontEndRenderingDef != null) return this._initFrontEndRenderingDef.promise; this._initFrontEndRenderingDef = new Deferred(); await this._waitFontRegistryInitialized(); for (let font of this.getFonts()) if (!this._fontRegistry.containsFonts([font])) await this._fontRegistry.loadFonts([font]); await this._initFrontEndRendering(); this._initFrontEndRenderingDef.resolve(); this._initFrontEndRenderingDef = null; } _waitFontRegistryInitialized() { if (this._fontRegistry != null) return Promise.resolve(); if (this._fontRegistryUpdated == null) this._fontRegistryUpdated = new Deferred(); return this._fontRegistryUpdated.promise; } _pathToTextWhizzPath(path) { return toTextWhizzPath(this._textWhizz, path); } get _isMobileTextEditorActive() { return this.textEditor instanceof MobileTextEditor; } _beforeFrontEndUpdate() { if (this.item.transform.isEmpty) return; const center = this.getControlCenter(); const transform = this.item.transform.clone(); transform.setAngle(0); this._modifyItem((i) => { var _a; this._applyTransform(i, transform, center); if (((_a = i.mask) === null || _a === void 0 ? void 0 : _a.vectorMask) != null) i.mask.vectorMask = this._getTransformedClippingPath(transform); i.transform.clear({ keepAngle: true, supressOnChanged: true }); }); } _isFrontEndRenderingInitialized() { return this._textEditorController != null && this._fontRegistry != null; } async _doFrontEndUpdate(beforeUpdate, afterUpdate, trigger) { if (this._isDisposed || this.canvas == null) { if (this._handlerUpdated != null) { this._handlerUpdated.resolve(); this._handlerUpdated = null; } return; } const innerUpdate = async () => { if (typeof beforeUpdate == "function") beforeUpdate(); this._beforeFrontEndUpdate(); try { await this._textEditorController.updateText(trigger); } catch (e) { console.log(this._textWhizz.getExceptionMessage(e)); console.log(this._textWhizz.getExceptionName(e)); throw e; } if (typeof afterUpdate == "function") afterUpdate(); if (this._handlerUpdated != null) { this._handlerUpdated.resolve(); this._handlerUpdated = null; } }; if (this.frontEndRenderingReady) { await innerUpdate(); } else { await this._waitLoadFonts(innerUpdate); } } _waitLoadFonts(innerUpdate) { this._waitLoadFontsLastInnerUpdate = innerUpdate; if (this._waitLoadFontsDef != null) return this._waitLoadFontsDef.promise; this._waitLoadFontsDef = new Deferred(); const promises = new Array(); promises.push(this._fontRegistry.loadFonts(this.getFonts())); Promise.all(promises) .then(() => { if (this._waitLoadFontsLastInnerUpdate) this._waitLoadFontsLastInnerUpdate(); this._waitLoadFontsDef.resolve(); this._waitLoadFontsDef = null; }) .catch((e) => { this._waitLoadFontsDef.reject(e); this._waitLoadFontsDef = null; }); return this._waitLoadFontsDef.promise; } _needToDrawBaseline() { if (this.isInEdit && this.textEditor.disableDrawBaseline) return false; const states = this._getBaselineDrawStates(); const currentState = this._getCurrentState(); if (states.includes(currentState)) return true; } _getBaselineDrawStates() { return []; } _getCurrentState() { if (this.isInEdit) return ItemHandlerState.edit; if (this.canvas.isItemHandlerSelected(this)) { if (this.canvas.isSelectionResizing) return ItemHandlerState.resize; if (this.canvas.isSelectionDragging) return ItemHandlerState.move; if (this.canvas.isSelectionRotating) return ItemHandlerState.rotate; return ItemHandlerState.select; } if (this.canvas.hoverHandler.currentHandler == this) return ItemHandlerState.hover; return ItemHandlerState.idle; } } NewBaseTextItemHandler.typeName = "NewBaseTextItemHandler"; //# sourceMappingURL=NewBaseTextItemHandler.js.map