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