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.

344 lines 15.5 kB
import { BaseRectangleItemHandler } from "./BaseRectangleItemHandler"; import { RotatedRectangleF, Transform, EqualsOfFloatNumbers } from "@aurigma/design-atoms-model/Math"; import { PlaceholderItemHandler } from "./PlaceholderItemHandler"; import { PlaceholderItem } from "@aurigma/design-atoms-model/Product/Items"; import { Collection } from "@aurigma/design-atoms-model/Collection"; import { Exception } from "@aurigma/design-atoms-model/Exception"; import { PlaceholderEditingViewMode } from "../Viewer/Interfaces"; export function isIContainerItemHandler(object) { return 'updateNestedItemHandlers' in object; } export class GroupItemHandler extends BaseRectangleItemHandler { constructor(item, itemHandlers, textWhizz = null) { super(null, null, null, null, item, textWhizz); this._itemHandlers = new Collection(); this._onChildItemHandlerChanging = (sender) => this.raiseChanging(this.item); if (Array.isArray(itemHandlers)) this.itemHandlers = new Collection(itemHandlers); this.item.items.add_itemAdded(this._onItemAdded.bind(this)); this.item.items.add_itemRemoved(this._onItemRemoved.bind(this)); this._subscribeItemHandlers(); } isHighlightNeeded() { return true; } _getColors() { const result = []; if (this.itemHandlers != null) { for (let handler of this.itemHandlers) { result.push(...handler.getColors()); } } result.push(...super._getColors()); return result; } _unsubscribeItemHandlers() { if (this.itemHandlers != null) { this.itemHandlers.remove_itemAdded(this._onItemHandlerAdded.bind(this)); this.itemHandlers.remove_itemRemoved(this._onItemHandlerRemoved.bind(this)); this.itemHandlers.forEach(itemHandler => itemHandler.getChangingEvent().remove(this._onChildItemHandlerChanging)); } } _subscribeItemHandlers() { if (this.itemHandlers != null) { this.itemHandlers.add_itemAdded(this._onItemHandlerAdded.bind(this)); this.itemHandlers.add_itemRemoved(this._onItemHandlerRemoved.bind(this)); this.itemHandlers.forEach(itemHandler => itemHandler.getChangingEvent().add(this._onChildItemHandlerChanging)); } } setItemHandlers(itemHandlers) { this._unsubscribeItemHandlers(); if (Array.isArray(itemHandlers)) this.itemHandlers = new Collection(itemHandlers); this._subscribeItemEvents(); } get itemHandlers() { return this._itemHandlers; } set itemHandlers(value) { if (value == null) throw new Error("ItemHandlers can't be null"); this._itemHandlers.clear(); this._itemHandlers.addRange(value); } drawItemHandler(itemHandlerCtx) { this.getNestedItemHandlers(true, false, true).forEach((itemHandler) => { var _a, _b; const isNormalPlaceholderViewMode = ((_b = (_a = this.canvas.viewerConfiguration) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.placeholderEditingViewMode) === PlaceholderEditingViewMode.Normal; if (itemHandler.canvas != null && (isNormalPlaceholderViewMode || !(itemHandler instanceof PlaceholderItemHandler && itemHandler.editing))) itemHandler.drawItemHandler(itemHandlerCtx); }); } _getChildrenHighlights() { let result = []; this.itemHandlers .where(x => x.isVisible()) .forEach((x) => { let rects = x.getHighlightRectangles(); result.push(...rects); }); return result; } getHighlightRectangles(options = { includeChildren: true, includeParent: false }) { let result = []; if (options.includeChildren) result = [...this._getChildrenHighlights()]; if (options.includeParent && this.item.groupItemPermissions) result.push(...super.getHighlightRectangles(options)); return result; } getOrderedItems() { return this.item.items.toArray(); } _onItemPropertyChanged(sender, propertyName) { switch (propertyName) { case "opacity": const newOpacity = sender.opacity; const updateOpacity = item => { if (!EqualsOfFloatNumbers(item.opacity, newOpacity)) item.opacity = newOpacity; if (item instanceof PlaceholderItem && !EqualsOfFloatNumbers(item.content.opacity, newOpacity)) item.updateContentAndFrames((i) => i.opacity = newOpacity); }; this.item.applyToItems(updateOpacity); break; } if (this._isPermissionsProperty(propertyName)) this._resetPermissionsCache(); super._onItemPropertyChanged(sender, propertyName); } _onItemAdded(data) { const { item, index } = data; item.addPropertyChanged(this._onChildItemPropertyChanged.bind(this)); if (this.canvas == null) return; if (index != null) this.itemHandlers.insertAt(index, this.canvas.getItemHandler(item)); else this.itemHandlers.add(this.canvas.getItemHandler(item)); } ; _onItemRemoved(data) { if (this.canvas == null) return; const itemHandler = this.itemHandlers.firstOrDefault(x => x.item == data.item); if (this.canvas.isItemHandlerSelected(itemHandler)) this.canvas.removeSelectedItemHandler(itemHandler); this.itemHandlers.remove(itemHandler); } _isPermissionsProperty(property) { switch (property) { case "itemPermissions": case "manipulationPermissions": case "visualizationPermissions": case "placeholderPermissions": return true; default: return false; } } _onChildItemPropertyChanged(sender, property) { if (this._isPermissionsProperty(property)) this._resetPermissionsCache(); } _onItemHandlerAdded(data) { const { item: itemHandler } = data; itemHandler.getChangingEvent().add(this._onChildItemHandlerChanging); const updateLayerAndCanvas = (itemHandler) => { itemHandler.layer = this.layer; itemHandler.canvas = this.canvas; if (itemHandler instanceof GroupItemHandler) itemHandler.applyToItems((itemHandler) => updateLayerAndCanvas(itemHandler)); }; updateLayerAndCanvas(itemHandler); this._resetPermissionsCache(); } _onItemHandlerRemoved(data) { const { item: itemHandler } = data; itemHandler.getChangingEvent().remove(this._onChildItemHandlerChanging); if (this.canvas.isItemHandlerSelected(data.item)) this.canvas.removeSelectedItemHandler(data.item); itemHandler.canvas = null; itemHandler.layer = null; itemHandler.item.parentContainer = null; this._resetPermissionsCache(); } ; replaceItemHandler(oldHandler, newHandler) { const index = this.itemHandlers.indexOf(oldHandler); if (index == -1) throw new Exception("ItemHandler not found"); this.itemHandlers.replaceAt(newHandler, index); newHandler.layer = this.layer; this._onItemHandlerRemoved({ item: oldHandler, index: index }); this._onItemHandlerAdded({ item: newHandler, index: index }); } getNestedItemHandlers(excludeGroupItems = false, reversedZorder = false, onlyVisible = false) { const allNestedHandlers = []; const itemHandlers = reversedZorder ? this.itemHandlers.toArray().slice().reverse() : this.itemHandlers.toArray().slice(); while (itemHandlers.length > 0) { const itemHandler = itemHandlers.shift(); if (onlyVisible && (!itemHandler.isVisible() || itemHandler.getPermissions().noShow)) continue; if (itemHandler instanceof GroupItemHandler) { const groupItemItemHandlers = reversedZorder ? itemHandler.itemHandlers.toArray().slice().reverse() : itemHandler.itemHandlers.toArray(); itemHandlers.unshift(...groupItemItemHandlers); if (excludeGroupItems) continue; } allNestedHandlers.push(itemHandler); } return allNestedHandlers; } updateNestedItemHandlers(updateFunc) { let result = false; for (let handler of this.itemHandlers) { let updateResult = updateFunc(handler); result = result || updateResult; if (isIContainerItemHandler(handler)) { updateResult = handler.updateNestedItemHandlers(updateFunc); result = result || updateResult; } } return result; } _onTransformRectangle(startRectangle, endRectangle, highlightOnly) { super._onTransformRectangle(startRectangle, endRectangle, highlightOnly); this.itemHandlers.forEach(itemHandler => itemHandler.transformRectangle(startRectangle, endRectangle, highlightOnly)); } async _updateImpl() { const promises = []; if (this.itemHandlers != null) { for (let itemHandler of this.itemHandlers) { promises.push(itemHandler.updateAsync()); } } await Promise.all(promises); await super._updateImpl(); } quickUpdate() { this.applyToItems(itemHandler => itemHandler.quickUpdate()); super.quickUpdate(); } onResized() { this.applyToItems(itemHandler => itemHandler.onResized()); return super.onResized(); } startTransform() { this.applyToItems(itemHandler => itemHandler.startTransform()); super.startTransform(); } _endTransform(changed, resized, supressOnChanged = false) { this.applyToItems(itemHandler => itemHandler.endTransform(changed, resized, true)); super._endTransform(changed, resized, supressOnChanged); } transformChanged() { super.transformChanged(); this.applyToItems(i => i.transformChanged()); } setRectangle(rectangle, supressOnChanged) { const { translateX, translateY, scaleX, scaleY, angle } = rectangle.getTransform(this.rectangle); const positioning = (itemHandler) => { const rect = itemHandler.rectangle; rect.translate(translateX, translateY); rect.rotateAt(angle, rectangle.center); itemHandler.setRectangle(rect, true); if (itemHandler instanceof PlaceholderItemHandler) itemHandler.updateContentAndFrames(positioning); }; this.itemHandlers.forEach(positioning); const positionedRectangle = this.rectangle; const scaling = (itemHandler) => { const rect = itemHandler.rectangle; const offsetX = rect.centerX - positionedRectangle.centerX; const offsetY = rect.centerY - positionedRectangle.centerY; rect.setTransform(new Transform(scaleX, scaleY, offsetX * (scaleX - 1), offsetY * (scaleY - 1))); itemHandler.setRectangle(rect, true); if (itemHandler instanceof PlaceholderItemHandler) itemHandler.updateContentAndFrames(scaling); }; this.itemHandlers.forEach(scaling); super.setRectangle(rectangle, supressOnChanged); } get _calculateRectangleFromChild() { return true; } _getRectangle() { if (!this._calculateRectangleFromChild) return super._getRectangle(); return this._getRectangleFromChildren(); } _getRectangleFromChildren() { let itemHandlers = this.itemHandlers.where(x => x.isVisible()); const rectangles = itemHandlers.toArray().map((itemHandler) => itemHandler.getTransformedRectangle(false, true)); if (rectangles.length < 1) return rectangles[0] != null ? rectangles[0] : new RotatedRectangleF(); const { angle } = this.item.transform; const { center } = rectangles.reduce((a, b) => RotatedRectangleF.union(a, b)); const { left, top, bottom, right } = rectangles .map(rectangle => rectangle.rotateAt(-angle, center).bounds) .reduce((a, b) => ({ left: Math.min(a.left, b.left), top: Math.min(a.top, b.top), right: Math.max(a.right, b.right), bottom: Math.max(a.bottom, b.bottom) })); return RotatedRectangleF.FromLTRB(left, top, right, bottom).rotateAt(angle, center); } _onAddedOnCanvas(canvas) { super._onAddedOnCanvas(canvas); this.applyToItems(itemHandler => itemHandler.canvas = canvas); } _onRemovedFromCanvas(canvas) { super._onRemovedFromCanvas(canvas); this.applyToItems(itemHandler => itemHandler.canvas = null); } applyToItems(func) { if (this.itemHandlers != null) for (var i = 0; i < this.itemHandlers.length; i++) func(this.itemHandlers.getItem([i])); } getPermissions() { if (this._cachedPermissions != null) return this._cachedPermissions; const permissions = super.getPermissions().clone(); for (const itemHandler of this.itemHandlers) { const ihPermissions = itemHandler.getPermissions(); if (!ihPermissions.allowMoveHorizontal) permissions.allowMoveHorizontal = false; if (!ihPermissions.allowMoveVertical) permissions.allowMoveVertical = false; if (!ihPermissions.allowRotate) permissions.allowRotate = false; if (!ihPermissions.resizeGrips.edge) permissions.resizeGrips.edge = false; if (!ihPermissions.resizeGrips.getCornerProportional()) permissions.resizeGrips.setCornerProportional(false); if (!ihPermissions.resizeGrips.getCornerArbitrary()) permissions.resizeGrips.setCornerArbitrary(false); if ((this.item.transform.angle - itemHandler.angle) % 90 !== 0) { permissions.resizeGrips.edge = false; permissions.resizeGrips.setCornerArbitrary(false); } } permissions.showSelectToolbarButton = this.item.groupItemPermissions.allowReplaceContent; this._cachedPermissions = permissions; return permissions; } resetPermissions() { super.resetPermissions(); for (const itemHandler of this.itemHandlers) { itemHandler.resetPermissions(); } this._resetPermissionsCache(); } isChildVisible(itemHandler) { return true; } get item() { return this._getItem(); } _resetPermissionsCache() { this._cachedPermissions = null; } } GroupItemHandler.typeName = "GroupItemHandler"; //# sourceMappingURL=GroupItemHandler.js.map