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.

404 lines 16.7 kB
import { LayoutItem, BaseTextItem, AutoLayoutSettings, GroupItem } from "@aurigma/design-atoms-model/Product/Items"; import { RotatedRectangleF, RectangleF, Transform } from "@aurigma/design-atoms-model/Math"; import { GroupItemHandler } from "./GroupItemHandler"; import { BaseRectangleItemHandler } from "./BaseRectangleItemHandler"; import { PlaceholderItemHandler } from "./PlaceholderItemHandler"; import { BaseTextItemHandler } from "./BaseTextItemHandler"; import { ItemUtils } from "../Utils/ItemUtils"; import { AutoLayoutHandler } from "./LayoutItem/AutoLayoutHandler"; import { EventObject } from "@aurigma/design-atoms-model/EventObject"; import { NewBaseTextItemHandler } from "./NewBaseTextItemHandler"; export class LayoutItemHandler extends GroupItemHandler { constructor(item, itemHandlers, _history, textWhizz = null) { super(item, itemHandlers, textWhizz); this._history = _history; this._layoutEvent = new EventObject(); this._visibilityState = null; this._visibilityStateChangedEvent = new EventObject(); this._isEmpty = null; this._disableApplyLayout = false; this._rectMap = {}; this._onChildItemChanged = (sender) => { var handler = this.canvas.getItemHandler(sender); var newRect = handler.rectangle; if (newRect.equals(this._rectMap[handler.uniqueId])) return; this._rectMap[handler.uniqueId] = newRect; this.applyLayout(); }; this._onChildItemHandlerVisibilityChanged = () => { this._updateVisibilityState(); this.applyLayout(); }; this._onChildItemHandlerLayout = (changed) => { if (changed) { this._updateVisibilityState(); this.applyLayout(); } }; this._onChildItemHandlerChanging = (sender) => { if (this._layoutHandler == null || !(this._layoutHandler instanceof AutoLayoutHandler)) this._resetSourceRectangle(); this.raiseChanging(this.item); }; this._transformStarted = false; this._transformedRectangle = null; this._applyMatrix = (matrix, finished, newAngle = null) => { const transform = (handler) => handler.setRectangle(handler.rectangle.transformByMatrix(matrix, newAngle), !finished); transform(this); if (!this._transformStarted) return; const layoutItemHandlers = [this]; while (layoutItemHandlers.length > 0) { const handler = layoutItemHandlers.shift(); const itemHandlers = handler.itemHandlers.ofType(BaseRectangleItemHandler); itemHandlers.forEach(i => { transform(i); if (i instanceof LayoutItemHandler) { layoutItemHandlers.push(i); } if (i instanceof PlaceholderItemHandler && i.content != null) { transform(i.content); } }); } }; this._onItemHandlerExitedEditMode = (sender) => { this._updateVisibilityState(); this.applyLayout(sender); }; this._onItemHandlerEnteredEditMode = (sender) => { this._updateVisibilityState(); }; this._onChildGroupItemsChanged = (sender, property) => { if (property == "items") { this._subscribeChildItemChanges(sender); } }; this._subscribeChildItemHandlers(); } getSelectionRectangle() { return this._getRectangleFromChildren(); } _getHighlightRectangle() { return this._getRectangleFromChildren(); } setItemHandlers(itemHandlers) { this._unsubscribeChildItemHandlers(); this._disableApplyLayout = true; super.setItemHandlers(itemHandlers); this._disableApplyLayout = false; this._initSourceRectangle().then(() => { this._initLayoutHandler(); this.applyLayout(null); }); this._subscribeChildItemHandlers(); } _isGroupHandler() { return true; } _onItemPropertyChanged(sender, propertyName) { switch (propertyName) { case "layoutSettings": this._initLayoutHandler(); break; } } _initLayoutHandler() { if (this.item.layoutSettings instanceof AutoLayoutSettings) { if (!(this._layoutHandler instanceof AutoLayoutHandler)) { this._layoutHandler = new AutoLayoutHandler(this.item, this.itemHandlers, this, this._history); this._layoutHandler.getLayoutEvent().add(this._onLayoutHandlerLayoutEvent.bind(this)); } else { this._layoutHandler._init(); } } else { if (this._layoutHandler != null) { this._layoutHandler.dispose(); } this._layoutHandler = null; } } getVisibilityStateChangedEvent() { return this._visibilityStateChangedEvent; } getLayoutEvent() { return this._layoutEvent; } _onLayoutHandlerLayoutEvent(changed) { if (this.canvas != null) { this.canvas.updateSelection(); this.canvas.updateButtonGroups({ placeholderHandler: this, placeholderHandlerPosition: true, violationContainerHandler: this, violationContainerHandlerPosition: true }); this.getChangingEvent().notify(this.item); this.canvas.redraw(); } this._layoutEvent.notify(changed); } async _initSourceRectangle() { if (this.item.sourceRectangle && !this.item.sourceRectangle.isEmpty()) return; await this._resetSourceRectangle(); } async _resetSourceRectangle() { await this.waitUpdate(); if (this.itemHandlers.any()) { const sourceRectangle = this.itemHandlers.cast().select(x => x.rectangle).aggregate((a, b) => RotatedRectangleF.union(a, b)); this.setSourceRectangle(sourceRectangle); } } async waitUpdate() { await Promise.all(this.itemHandlers.toArray().map((vo) => { return vo.waitUpdate(); })); } startTransform() { this._originalHeight = this.height; this._transformStarted = true; if (this._layoutHandler) this._layoutHandler.ignoreLayoutApply = true; super.startTransform(); } onResized() { var scale = this.height / this._originalHeight; if (this.item.layoutSettings != null && this.item.layoutSettings instanceof AutoLayoutSettings) this.item.layoutSettings.margin *= scale; return super.onResized(); } _endTransform(changed, resized, suppressOnChanged) { var _a, _b, _c, _d; super._endTransform(changed, resized, suppressOnChanged); if (this._transformedRectangle == null) { this._transformStarted = false; if (this._layoutHandler) this._layoutHandler.ignoreLayoutApply = false; return; } (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.pauseRedraw(); var t = this._transformedRectangle; this._transformedRectangle = null; this._transformStarted = false; //await this.waitUpdate(); (_b = this._history) === null || _b === void 0 ? void 0 : _b.pause(); this.setSourceRectangle(t); if (this._layoutHandler) this._layoutHandler.ignoreLayoutApply = false; this.applyLayout(null); (_c = this._history) === null || _c === void 0 ? void 0 : _c.resume(true, false, true); (_d = this.canvas) === null || _d === void 0 ? void 0 : _d.continueRedraw(); } _getChildrenHighlights() { if (this._layoutHandler == null) return []; let result = []; this.itemHandlers .toArray() .filter(itemHandler => this._layoutHandler._filterHiddenItems(itemHandler)) .forEach((itemHandler) => result.push(...itemHandler.getHighlightRectangles())); return result; } get _calculateRectangleFromChild() { return false; } _getRectangle() { if (this._transformedRectangle) return this._transformedRectangle; return super._getRectangle(); } isEmpty() { const value = this._calculateIsEmpty(); this._updateIsEmpty(value); return value; } isVisible() { return super.isVisible() && !this.isEmpty(); } async applyLayout(sender) { if (this._disableApplyLayout) return; if (sender instanceof PlaceholderItemHandler && sender.editing) return; await this.waitUpdate(); if (this.item.layoutSettings instanceof AutoLayoutSettings && this._layoutHandler) { this._layoutHandler.applyLayout(); } else { this._resetSourceRectangle(); this._onLayoutHandlerLayoutEvent(false); } } getControlBounds() { if (!this.item.sourceRectangle) return new RectangleF(); return this.item.sourceRectangle; } setRectangle(rectangle, suppressOnChanged, updateChildren = true) { if (this._transformStarted) { this._transformedRectangle = rectangle.clone(); if (updateChildren) super.setRectangle(rectangle, suppressOnChanged); return; } if (updateChildren) super.setRectangle(rectangle, suppressOnChanged); this.setSourceRectangle(rectangle); } setSourceRectangle(rectangle) { this.item.sourceRectangle = rectangle.toRectangleF(); this.item.transform = new Transform(1, 1, 0, 0, rectangle.angle); } getOrderedItems() { let result = null; if (this.item.layoutSettings instanceof AutoLayoutSettings && this._layoutHandler != null) result = this._layoutHandler.getOrderedItems(); else result = super.getOrderedItems(); return result; } generateAndApplyAutolayoutSettings(alignItems, orientation, margin, justifyContent) { this.item.layoutSettings = LayoutItem.generateAutoLayoutSettings(this.itemHandlers.toArray().map((itemHandler) => itemHandler.getTransformedRectangle(false, true).bounds), alignItems, orientation, margin, justifyContent); } async _onItemAdded(data) { super._onItemAdded(data); if (data.item instanceof BaseTextItem) { await ItemUtils.waitForItemsUpdated([data.item], this.canvas); } this._subscribeChildItemChanges(data.item); this.applyLayout(this.itemHandlers.first(itemHandler => itemHandler.item === data.item)); } _onItemRemoved(data) { super._onItemRemoved(data); this._unsubscribeChildItemChanges(data.item); if (this._layoutHandler) this._layoutHandler.onItemRemoved(data); else this._resetSourceRectangle(); } async _onItemHandlerAdded(data) { super._onItemHandlerAdded(data); if (this._layoutHandler instanceof AutoLayoutHandler) this._layoutHandler.onItemHandlersCollectionChanged(); this.applyLayout(); } _updateVisibilityState() { let visible = this.isVisible(); if (visible === this._visibilityState) return; this._visibilityState = visible; this._onVisibilityStateChanged(); } _onVisibilityStateChanged() { this.applyLayout(); this._visibilityStateChangedEvent.notify(); } _onItemHandlerRemoved(data) { super._onItemHandlerRemoved(data); if (this._layoutHandler instanceof AutoLayoutHandler) this._layoutHandler.onItemHandlersCollectionChanged(); } ; _subscribeChildItemHandlers() { var _a; (_a = this.itemHandlers) === null || _a === void 0 ? void 0 : _a.forEach(x => this._subscribeChildItemHandler(x)); } _unsubscribeChildItemHandlers() { this.itemHandlers.forEach(x => this._unsubscribeChildItemHandler(x)); } _subscribeChildItemHandler(itemHandler) { itemHandler.getChangingEvent().add(this._onChildItemHandlerChanging); if (itemHandler instanceof NewBaseTextItemHandler) { itemHandler.exitedEditModeEvent.add(this._onItemHandlerExitedEditMode); itemHandler.enteredEditModeEvent.add(this._onItemHandlerEnteredEditMode); } if (itemHandler instanceof LayoutItemHandler) { itemHandler.getLayoutEvent().add(this._onChildItemHandlerLayout); itemHandler.getVisibilityStateChangedEvent().add(this._onChildItemHandlerVisibilityChanged); } } _unsubscribeChildItemHandler(itemHandler) { itemHandler.getChangingEvent().remove(this._onChildItemHandlerChanging); if (itemHandler instanceof NewBaseTextItemHandler) { itemHandler.exitedEditModeEvent.remove(this._onItemHandlerExitedEditMode); itemHandler.enteredEditModeEvent.remove(this._onItemHandlerEnteredEditMode); } if (itemHandler instanceof LayoutItemHandler) { itemHandler.getLayoutEvent().remove(this._onChildItemHandlerLayout); itemHandler.getVisibilityStateChangedEvent().remove(this._onChildItemHandlerVisibilityChanged); } } _unsubscribeChildItems() { this.item.items.forEach(x => this._unsubscribeChildItemChanges(x)); } _subscribeChildItems() { this.item.items.forEach(x => this._subscribeChildItemChanges(x)); } _unsubscribeChildItemChanges(item) { if (item instanceof GroupItem) { item.applyToItems(x => this._unsubscribeChildItemChanges(x)); item.removePropertyChanged(this._onChildGroupItemsChanged); } item.getItemChangedEvent().remove(this._onChildItemChanged); } _subscribeChildItemChanges(item) { if (item instanceof GroupItem) { item.applyToItems(x => this._subscribeChildItemChanges(x)); item.addPropertyChanged(this._onChildGroupItemsChanged); } item.getItemChangedEvent().add(this._onChildItemChanged); } async _onRemovedFromCanvas(canvas) { this._unsubscribeChildItems(); this._unsubscribeChildItemHandlers(); super._onRemovedFromCanvas(canvas); } async _onAddedOnCanvas(canvas) { super._onAddedOnCanvas(canvas); this._subscribeChildItems(); this._initLayoutHandler(); await this._initSourceRectangle(); } drawItemHandler(itemHandlerCtx) { if (this.isEmpty()) return; super.drawItemHandler(itemHandlerCtx); } get item() { return this._getItem(); } isChildVisible(childItemHandler) { if (childItemHandler instanceof BaseTextItemHandler || childItemHandler instanceof NewBaseTextItemHandler) { return !childItemHandler.isEmpty(); } return true; } _calculateIsEmpty() { var itemHandlersToCheck = this.itemHandlers.where(x => { let result = false; if ((x instanceof BaseTextItemHandler || x instanceof NewBaseTextItemHandler) && !x.isLocked()) result = true; else if (x instanceof LayoutItemHandler) result = true; return result; }); if (!itemHandlersToCheck.any()) return false; const hasNonEmptyChildren = itemHandlersToCheck.any(element => !element.isEmpty()); var result = !hasNonEmptyChildren; return result; } _updateIsEmpty(value) { if (value === this._isEmpty) return; this._isEmpty = value; this._onEmptyStateChanged(); } _onEmptyStateChanged() { this.itemHandlers.forEach(x => x.update()); } } LayoutItemHandler.typeName = "LayoutItemHandler"; //# sourceMappingURL=LayoutItemHandler.js.map