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