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