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.

475 lines 25.2 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; import { EventObject } from "@aurigma/design-atoms-model/EventObject"; import { PointF, RectangleF, RotatedRectangleF } from "@aurigma/design-atoms-model/Math"; import { AutoLayoutSettings, AutoLayoutAlignItems, AutoLayoutOrientation, AutoLayoutAnchorPoint } from "@aurigma/design-atoms-model/Product/Items"; import { BaseTextItemHandler, NewBaseTextItemHandler, PlaceholderItemHandler } from ".."; import { getTranslationTransform } from "../../Utils/Math"; import { LayoutItemHandler } from "../LayoutItemHandler"; import { GroupItemHandler } from "../GroupItemHandler"; var AutoLayoutHandler = /** @class */ (function () { function AutoLayoutHandler(_item, _itemHandlers, _itemHandler, _history) { var _this = this; this._item = _item; this._itemHandlers = _itemHandlers; this._itemHandler = _itemHandler; this._history = _history; this._layoutEvent = new EventObject(); this._orderedItemHandlers = null; this._initialized = false; this._disposed = false; this._onChildItemHandlerChanging = function (sender) { _this.applyLayout(); }; this._onChildItemHandlerPropertyChanged = function (sender, propertyName) { return __awaiter(_this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = propertyName; switch (_a) { case "font": return [3 /*break*/, 1]; case "text": return [3 /*break*/, 1]; case "tracking": return [3 /*break*/, 1]; case "leading": return [3 /*break*/, 1]; case "shadow": return [3 /*break*/, 1]; case "stroke": return [3 /*break*/, 1]; case "underline": return [3 /*break*/, 1]; case "sourceRectangle": return [3 /*break*/, 1]; case "borderWidth": return [3 /*break*/, 1]; case "transform": return [3 /*break*/, 1]; } return [3 /*break*/, 3]; case 1: return [4 /*yield*/, sender.waitUpdate()]; case 2: _b.sent(); this.applyLayout(); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; this._onItemPropertyChanged = function (sender, propertyName) { switch (propertyName) { case "layoutSettings": _this._orderedItemHandlers = null; _this._updateItemsOrder(); _this.applyLayout(); break; case "margin": _this.applyLayout(); break; case "orientation": _this.applyLayout(true); break; case "alignItems": case "justifyContent": _this.applyLayout(); break; } }; this._ignoreLayoutApply = false; this._filterHiddenItems = function (itemHandler) { return !((itemHandler instanceof BaseTextItemHandler || itemHandler instanceof NewBaseTextItemHandler || itemHandler instanceof LayoutItemHandler) && itemHandler.isEmpty()); }; this._item.addPropertyChanged(this._onItemPropertyChanged); this._itemHandlers.add_itemAdded(this._onItemHandlerAdded.bind(this)); this._itemHandlers.add_itemRemoved(this._onItemHandlerRemoved.bind(this)); this._itemHandlers.forEach(function (itemHandler) { return itemHandler.addItemPropertyChanged(_this._onChildItemHandlerPropertyChanged); }); this._init(); } AutoLayoutHandler.prototype.dispose = function () { var _this = this; this._disposed = true; this._item.removePropertyChanged(this._onItemPropertyChanged); this._itemHandlers.remove_itemAdded(this._onItemHandlerAdded.bind(this)); this._itemHandlers.remove_itemRemoved(this._onItemHandlerRemoved.bind(this)); this._itemHandlers.forEach(function (itemHandler) { return itemHandler.removeItemPropertyChanged(_this._onChildItemHandlerPropertyChanged); }); }; AutoLayoutHandler.prototype.getLayoutEvent = function () { return this._layoutEvent; }; AutoLayoutHandler.prototype.onItemRemoved = function (data) { this._updateItemsOrder({ removedItem: data.item }); this.applyLayout(); }; AutoLayoutHandler.prototype.onItemHandlersCollectionChanged = function () { this._orderedItemHandlers = null; }; AutoLayoutHandler.prototype._init = function () { return __awaiter(this, void 0, void 0, function () { var order; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this._initialized) return [2 /*return*/]; order = this._item.getItemsOrder(); return [4 /*yield*/, this._itemHandler.waitUpdate()]; case 1: _a.sent(); if (!order) this._updateItemsOrder(); this._initialized = true; this.applyLayout(); return [2 /*return*/]; } }); }); }; AutoLayoutHandler.prototype._onItemHandlerAdded = function (data) { data.item.addItemPropertyChanged(this._onChildItemHandlerPropertyChanged); this._orderedItemHandlers = null; }; AutoLayoutHandler.prototype._onItemHandlerRemoved = function (data) { data.item.removeItemPropertyChanged(this._onChildItemHandlerPropertyChanged); this._orderedItemHandlers = null; }; AutoLayoutHandler.prototype._updateItemsOrder = function (params) { if (this._item.layoutSettings instanceof AutoLayoutSettings) { if (this._validateItemsOrder()) return; var itemsOrder = this._item.getItemsOrder(); if (itemsOrder == null) { this._initSortedItemHandlers(); var ids = this._getSortedItemHandlers().map(function (x) { return x.item.id; }); this._item.setItemsOrder(ids); } } }; AutoLayoutHandler.prototype._initSortedItemHandlers = function () { var groupCenter = this._itemHandler.getTransformedRectangle(false, true).center; var angle = this._item.transform.angle; var orientation = this._item.layoutSettings.orientation; var sortFunc = function (a, b) { return orientation === AutoLayoutOrientation.horizontal ? a.bounds.left - b.bounds.left : a.bounds.top - b.bounds.top; }; this._orderedItemHandlers = this._itemHandlers.toArray().sort(function (a, b) { return sortFunc(a.getTransformedRectangle(false, true).rotateAt(-angle, groupCenter), b.getTransformedRectangle(false, true).rotateAt(-angle, groupCenter)); }); return this._orderedItemHandlers; }; AutoLayoutHandler.prototype._validateItemsOrder = function () { var layoutItemsOrder = this._item.getItemsOrder(); if (layoutItemsOrder == null) return false; if (layoutItemsOrder.length !== this._item.items.length) return false; var itemIds = this._item.items.select(function (x) { return x.id; }).toArray(); return layoutItemsOrder.every(function (x) { return itemIds.includes(x); }); }; AutoLayoutHandler.prototype._getSortedItemHandlers = function () { if (this._orderedItemHandlers != null) return this._orderedItemHandlers; var itemsOrder = this._item.getItemsOrder(); if (!itemsOrder) return null; var sortedItemHandlers = []; var itemHandlers = this._itemHandlers.toArray(); if (itemHandlers.length != itemsOrder.length) { throw new Error("itemsOrder length does not match itemHandlers length"); } itemsOrder.forEach(function (itemsOrderElement) { var i = itemHandlers.findIndex(function (x) { return x.item.id == itemsOrderElement; }); if (i == -1) throw new Error("itemsOrder: Element with id " + itemsOrderElement + " was not found in itemHandlers"); sortedItemHandlers.push(itemHandlers[i]); itemHandlers.splice(i, 1); }); this._orderedItemHandlers = sortedItemHandlers; return this._orderedItemHandlers; }; AutoLayoutHandler.prototype.getOrderedItems = function () { var itemsOrder = this._item.getItemsOrder(); if (itemsOrder) { var result = this._item.items.toArray(); result.sort(function (x, y) { return itemsOrder.indexOf(x.id) - itemsOrder.indexOf(y.id); }); return result; } return null; }; Object.defineProperty(AutoLayoutHandler.prototype, "ignoreLayoutApply", { set: function (value) { this._ignoreLayoutApply = value; }, enumerable: true, configurable: true }); AutoLayoutHandler.prototype.applyLayout = function (fromCenter) { if (fromCenter === void 0) { fromCenter = false; } var _a, _b, _c, _d, _e, _f; if (this._disposed) return; if (!this._initialized) return; if (this._ignoreLayoutApply) return; this._ignoreLayoutApply = true; try { var historyActive = !((_a = this._history) === null || _a === void 0 ? void 0 : _a.isPaused()); if (historyActive) (_b = this._history) === null || _b === void 0 ? void 0 : _b.pause(); (_c = this._itemHandler.canvas) === null || _c === void 0 ? void 0 : _c.pauseRedraw(); var changed = this._applyLayoutImpl(fromCenter); (_d = this._itemHandler.canvas) === null || _d === void 0 ? void 0 : _d.continueRedraw(); if (historyActive) { if (changed) (_e = this._history) === null || _e === void 0 ? void 0 : _e.resume(true, false, true); else (_f = this._history) === null || _f === void 0 ? void 0 : _f.resume(false, false, true); } this._layoutEvent.notify(changed); } finally { this._ignoreLayoutApply = false; } }; AutoLayoutHandler.prototype._applyLayoutImpl = function (fromCenter) { var _this = this; if (fromCenter === void 0) { fromCenter = false; } var _a; var sortedItemHandlers = this._getSortedItemHandlers(); if (sortedItemHandlers == null || sortedItemHandlers.length == 0) return; var originalRectangle = this._itemHandler.rectangle; var originalCenter = originalRectangle.center; var _b = this._item.layoutSettings, alignItems = _b.alignItems, orientation = _b.orientation, margin = _b.margin, anchorPoint = _b.anchorPoint; var angle = this._item.transform.angle; var layoutRect = originalRectangle.toRectangleF(); var layoutAnchorPoint = this._getAnchorPoint(layoutRect, anchorPoint, orientation); var currentPoint = this._getOriginalPoint(layoutRect, alignItems, orientation); sortedItemHandlers = sortedItemHandlers.filter(function (itemHandler) { return _this._filterHiddenItems(itemHandler); }); var rects = []; sortedItemHandlers.forEach(function (element) { var elementPositionRect = _this._getItemHandlerPositionRect(element, originalRectangle, currentPoint, alignItems, orientation); var offset = _this._getPositionRectOffset(orientation, layoutRect, elementPositionRect) + margin; currentPoint = _this._getOriginalPoint(layoutRect, alignItems, orientation, offset); rects.push(elementPositionRect); }); rects = this._applyAnchor(rects, layoutRect, anchorPoint, orientation); var anyChildChanged = false; sortedItemHandlers.forEach(function (element) { var elementPositionRect = rects.shift(); var changed = _this._setItemHandlerPosition(element, originalRectangle, elementPositionRect); anyChildChanged = anyChildChanged || changed; }); var filteredItems = this._itemHandlers.cast().where(this._filterHiddenItems); var sourceRectChanged = false; if (filteredItems.any()) { var childItemsBounds = filteredItems.select(function (x) { return x.getTransformedRectangle(false, true); }).aggregate(function (a, b) { return RotatedRectangleF.union(a, b); }); var newSourceRectangle = this._getSourceRectangleByAnchorPoint(childItemsBounds, layoutAnchorPoint, orientation, anchorPoint); if (fromCenter) { var translationTransform = getTranslationTransform(newSourceRectangle.center, originalCenter); newSourceRectangle.setTransform(translationTransform); } this._itemHandler.setSourceRectangle(newSourceRectangle); sourceRectChanged = !originalRectangle.equals(newSourceRectangle, 0.01); } var changed = anyChildChanged || sourceRectChanged; // TODO: move outside if (changed) (_a = this._itemHandler.canvas) === null || _a === void 0 ? void 0 : _a.updateTexts(); return changed; }; AutoLayoutHandler.prototype._getSourceRectangleByAnchorPoint = function (childBounds, layoutAnchorPoint, orientation, anchor) { var angle = childBounds.angle; var childRect = childBounds.toRectangleF(); if (orientation == AutoLayoutOrientation.horizontal) { if (anchor == AutoLayoutAnchorPoint.start) { childRect.left = layoutAnchorPoint.x; } else if (anchor == AutoLayoutAnchorPoint.center) { var dx = childRect.center.x - layoutAnchorPoint.x; childRect.left -= dx; } else { // end childRect.right = layoutAnchorPoint.x; } } else { // vertical if (anchor == AutoLayoutAnchorPoint.start) { childRect.top = layoutAnchorPoint.y; } else if (anchor == AutoLayoutAnchorPoint.center) { var dy = childRect.center.y - layoutAnchorPoint.y; childRect.top -= dy; } else { // end childRect.bottom = layoutAnchorPoint.y; } } return RotatedRectangleF.fromRectangleF(childRect, angle); }; AutoLayoutHandler.prototype._getAnchorPoint = function (layoutRect, anchorPoint, orientation) { if (orientation == AutoLayoutOrientation.horizontal) { var y = layoutRect.center.y; switch (anchorPoint) { case AutoLayoutAnchorPoint.start: return new PointF(layoutRect.left, y); case AutoLayoutAnchorPoint.center: return new PointF(layoutRect.center.x, y); case AutoLayoutAnchorPoint.end: return new PointF(layoutRect.right, y); } } else { var x = layoutRect.center.x; switch (anchorPoint) { case AutoLayoutAnchorPoint.start: return new PointF(x, layoutRect.top); case AutoLayoutAnchorPoint.center: return new PointF(x, layoutRect.center.y); case AutoLayoutAnchorPoint.end: return new PointF(x, layoutRect.bottom); } } }; AutoLayoutHandler.prototype._applyAnchor = function (inputRects, layoutRect, anchorPoint, orientation) { if (inputRects.length == 0) return inputRects; if (anchorPoint == AutoLayoutAnchorPoint.start) return inputRects; var calculateDiff = function (rects) { var dx = 0; var dy = 0; var unionRect = rects.reduce(function (prev, current) { return RectangleF.union(prev, current); }); if (orientation == AutoLayoutOrientation.horizontal) { if (anchorPoint == AutoLayoutAnchorPoint.center) dx = unionRect.center.x - layoutRect.center.x; else if (anchorPoint == AutoLayoutAnchorPoint.end) dx = unionRect.right - layoutRect.right; else throw new Error("Invalid _applyAnchor operation. Orientation: '" + orientation + "' AnchorPoint: '" + anchorPoint + "'"); } else { // vertical if (anchorPoint == AutoLayoutAnchorPoint.center) dy = unionRect.center.y - layoutRect.center.y; else if (anchorPoint == AutoLayoutAnchorPoint.end) dy = unionRect.bottom - layoutRect.bottom; else throw new Error("Invalid _applyAnchor operation. Orientation: '" + orientation + "' AnchorPoint: '" + anchorPoint + "'"); } return new PointF(dx, dy); }; var diff = calculateDiff(inputRects); return inputRects.map(function (x) { return new RectangleF(x.left - diff.x, x.top - diff.y, x.width, x.height); }); }; AutoLayoutHandler.prototype._setItemHandlerPosition = function (itemHandler, originalRectangle, elementPositionRect) { var _this = this; var setRectangle = function (itemHandler) { var itemHandlerRect = itemHandler.getTransformedRectangle(false, true); var originalRect = itemHandlerRect.clone(); itemHandlerRect.rotateAt(-originalRectangle.angle, originalRectangle.center); var itemHandlerRectBounds = itemHandlerRect.bounds; var dx = elementPositionRect.left - itemHandlerRectBounds.left; var dy = elementPositionRect.top - itemHandlerRectBounds.top; itemHandlerRect.translate(dx, dy); itemHandlerRect.rotateAt(originalRectangle.angle, originalRectangle.center); if (originalRect.equals(itemHandlerRect)) return false; _this._setItemHandlerRectangle(itemHandler, itemHandlerRect, setRectangle); return true; }; return setRectangle(itemHandler); }; AutoLayoutHandler.prototype._setItemHandlerRectangle = function (itemHandler, itemHandlerRect, setRectangleFunc) { var margin = itemHandler.getBorderMargin(); itemHandlerRect.width -= margin * 2; itemHandlerRect.height -= margin * 2; if (itemHandler instanceof LayoutItemHandler) { itemHandler.setRectangle(itemHandlerRect, true, true); } else { itemHandler.setRectangle(itemHandlerRect); if (itemHandler instanceof PlaceholderItemHandler) itemHandler.updateContentAndFrames(setRectangleFunc); if (itemHandler instanceof GroupItemHandler) { itemHandler.getNestedItemHandlers(true).forEach(function (item) { setRectangleFunc(item); }); } } }; AutoLayoutHandler.prototype._getPositionRectOffset = function (orientation, layoutRect, elementPositionRect) { if (orientation == AutoLayoutOrientation.vertical) { return elementPositionRect.bottom - layoutRect.top; } else { // horizontal return elementPositionRect.right - layoutRect.left; } }; AutoLayoutHandler.prototype._getItemHandlerPositionRect = function (element, layoutRectangle, currentPoint, alignItems, orientation) { var itemHandlerRectangle = element.getTransformedRectangle(false, true); itemHandlerRectangle.angle -= layoutRectangle.angle; var itemHandlerBounds = itemHandlerRectangle.bounds; var itemHandlerPoint = this._getOriginalPoint(itemHandlerBounds, alignItems, orientation); var dx = currentPoint.x - itemHandlerPoint.x; var dy = currentPoint.y - itemHandlerPoint.y; if (alignItems !== AutoLayoutAlignItems.none || orientation === AutoLayoutOrientation.horizontal) itemHandlerBounds.left += dx; if (alignItems !== AutoLayoutAlignItems.none || orientation === AutoLayoutOrientation.vertical) itemHandlerBounds.top += dy; return itemHandlerBounds; }; AutoLayoutHandler.prototype._getOriginalPoint = function (layoutRect, alignItems, orientation, offset) { if (offset === void 0) { offset = 0; } var result; if (orientation == AutoLayoutOrientation.vertical) { if (alignItems == AutoLayoutAlignItems.start || alignItems == AutoLayoutAlignItems.none) { result = new PointF(layoutRect.left, layoutRect.top); } else if (alignItems == AutoLayoutAlignItems.center) { result = new PointF(layoutRect.center.x, layoutRect.top); } else { result = new PointF(layoutRect.right, layoutRect.top); } result.y += offset; } else { // horizontal if (alignItems == AutoLayoutAlignItems.start || alignItems == AutoLayoutAlignItems.none) result = new PointF(layoutRect.left, layoutRect.top); else if (alignItems == AutoLayoutAlignItems.center) result = new PointF(layoutRect.left, layoutRect.center.y); else result = new PointF(layoutRect.left, layoutRect.bottom); result.x += offset; } return result; }; return AutoLayoutHandler; }()); export { AutoLayoutHandler }; //# sourceMappingURL=AutoLayoutHandler.js.map