@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
250 lines • 13.8 kB
JavaScript
import { getStringEnumValue } from "@aurigma/design-atoms-model/Utils/Utils";
import { ArgumentException } from "@aurigma/design-atoms-model/Exception";
import { BaseRectangleItemHandler, NewBaseTextItemHandler } from "../../ItemHandlers";
import { EqualsOfFloatNumbers, RotatedRectangleF } from "@aurigma/design-atoms-model/Math";
import { FloatingToolbarElementHandler, UpdatePositionMode } from "./FloatingToolbarElementHandler";
import { isPlaceholder, isImageOrPlaceholder, isGroup } from "../../ItemHandlers/HandlerUtils";
import { uniq } from "@aurigma/utils-js";
export class FloatingToolbarManager {
constructor(_canvasElementHandler, _viewer, _canvas, _selectionHandler, config) {
this._canvasElementHandler = _canvasElementHandler;
this._viewer = _viewer;
this._canvas = _canvas;
this._selectionHandler = _selectionHandler;
this._dndIsInProgress = false;
this._isInEditMode = false;
this._handleId = "Handle";
this._selectId = "Select";
this._editId = "Edit";
this._deleteId = "Delete";
this._onItemHandlerHover = (handlers) => {
if (this._config.mode !== FloatingToolbarMode.Inside)
return;
const firstImageOrPlaceholderItemHandler = handlers === null || handlers === void 0 ? void 0 : handlers.find(h => isImageOrPlaceholder(h));
if (firstImageOrPlaceholderItemHandler == null) {
if (this._currentHandlerItem != this._selectedHandler)
this._setCurrentItemHandler(this._selectedHandler);
}
if (this._getPositionMode(firstImageOrPlaceholderItemHandler) === UpdatePositionMode.Center) {
const oldCurrentHandler = this._currentHandlerItem;
const visible = this._floatingToolbarElementHandler.visible;
if (visible)
this._floatingToolbarElementHandler.changeVisibility(false);
this._setCurrentItemHandler(firstImageOrPlaceholderItemHandler);
if (!this._floatingToolbarElementHandler.isElementVisible || this._floatingToolbarElementHandler.isToolbarLargerThanRectangle(firstImageOrPlaceholderItemHandler.rectangle)) {
this._setCurrentItemHandler(oldCurrentHandler);
this._floatingToolbarElementHandler.changeVisibility(visible);
}
else {
this._updateView();
}
}
};
this._onSelectButtonClick = () => {
this._eventManager.selectToolbarButtonClickEvent.notify(this._currentHandlerItem.item);
};
this._onHandleButtonClick = () => {
this._eventManager.handleToolbarButtonClickEvent.notify(this._currentHandlerItem.item);
};
this._onEditButtonClick = () => {
this._eventManager.editToolbarButtonClickEvent.notify(this._currentHandlerItem.item);
};
this._onDeleteButtonClick = () => {
this._eventManager.deleteToolbarButtonClickEvent.notify(this._currentHandlerItem.item);
};
this._setCurrentItemHandler = (itemHandler) => {
if (this._currentHandlerItem == itemHandler)
return;
if (this._currentHandlerItem instanceof NewBaseTextItemHandler) {
this._currentHandlerItem.exitedEditModeEvent.remove(this._currentItemHandlerExitedEditMode);
this._currentHandlerItem.enteredEditModeEvent.remove(this._currentItemHandlerEnteredEditMode);
}
this._currentHandlerItem = itemHandler;
this._isInEditMode = false;
if (this._currentHandlerItem instanceof NewBaseTextItemHandler) {
this._currentHandlerItem.exitedEditModeEvent.add(this._currentItemHandlerExitedEditMode);
this._currentHandlerItem.enteredEditModeEvent.add(this._currentItemHandlerEnteredEditMode);
}
if (itemHandler == null)
return this._floatingToolbarElementHandler.changeVisibility(false);
this._fullUpdate();
};
this._currentItemHandlerExitedEditMode = () => {
this._isInEditMode = false;
this._fullUpdate();
};
this._currentItemHandlerEnteredEditMode = () => {
this._isInEditMode = true;
this._fullUpdate();
};
this._updateButtonsVisibility = () => {
if (this._currentHandlerItem == null || this._descriptors == null)
return;
const perms = this._getCurrentPermissions();
this._floatingToolbarElementHandler.changeButtonsVisibility([
{ id: this._deleteId, visible: perms.delete },
{ id: this._editId, visible: perms.edit },
{ id: this._selectId, visible: perms.select },
{ id: this._handleId, visible: perms.handle },
].filter(param => this._descriptors.has(param.id)));
};
this._getCurrentPermissions = () => {
if (this._currentHandlerItem == null)
return null;
const handler = this._currentHandlerItem;
return {
delete: handler.showDeleteToolbarButton() && !this._canvas.simpleMode,
edit: handler.showEditToolbarButton(),
select: (isImageOrPlaceholder(handler) || isGroup(handler)) && handler.showSelectToolbarButton(),
handle: handler.showHandleToolbarButton()
};
};
this._onItemPropertyChanged = (sender, propName) => {
var _a;
if (((_a = this._currentHandlerItem) === null || _a === void 0 ? void 0 : _a.item) != sender)
return;
if (propName === "transform" || propName === "content" || propName === "source" || propName === "permissions") {
this._fullUpdate();
}
};
this._fullUpdate = () => {
this._updateButtonsVisibility();
this._updateView();
};
this._onSelectedItemChanged = () => {
const handlers = this._selectionHandler.selectedItemHandlers.ofType(BaseRectangleItemHandler);
const current = handlers.count() == 1 ? handlers.first() : null;
this._setCurrentItemHandler(current);
this._selectedHandler = current;
};
this._updateView = () => {
if (!this._isShowFloatingItemToolbar) {
return this._floatingToolbarElementHandler.changeVisibility(false);
}
if (this._isInEditMode)
return this._floatingToolbarElementHandler.changeVisibility(false);
const visibility = this._floatingToolbarElementHandler.changeVisibility(true);
if (visibility)
this._updatePosition();
};
this._updatePosition = () => {
var _a;
const visibleRect = (_a = this._currentHandlerItem) === null || _a === void 0 ? void 0 : _a.rectangle;
if (visibleRect == null)
return;
const rect = RotatedRectangleF.getRectWithOffset(visibleRect, this._canvas.offset);
this._floatingToolbarElementHandler.updatePosition(rect, this._getPositionMode(this._currentHandlerItem));
};
this._onDndStarted = () => {
this._dndIsInProgress = true;
this._updateView();
};
this._onDndFinished = () => {
this._dndIsInProgress = false;
this._updateView();
};
this.configuration = config;
}
set configuration(conf) {
var _a, _b, _c;
(_a = this._floatingToolbarElementHandler) === null || _a === void 0 ? void 0 : _a.dispose();
this._config = Object.assign(Object.assign({}, this._defaultConfig), (conf || {}));
const mode = getStringEnumValue(FloatingToolbarMode, this._config.mode);
if (mode == null)
throw new ArgumentException(`Canvas.ts: cannot parse FloatingToolbarMode: ${mode}`);
this._config.mode = mode;
const allowedButtons = [this._handleId, this._selectId, this._editId, this._deleteId];
const buttons = uniq((_c = (_b = this._config.buttons) === null || _b === void 0 ? void 0 : _b.map(b => allowedButtons.find(ab => ab.toLowerCase() === b.toLowerCase()))) === null || _c === void 0 ? void 0 : _c.filter(b => b != null));
if (buttons.length === 0)
return;
const descriptions = [
[this._handleId, { cssClass: this._config.handleButtonClass, defaultText: this._handleId, handler: this._onHandleButtonClick, visible: true }],
[this._selectId, { cssClass: this._config.selectButtonClass, defaultText: this._selectId, handler: this._onSelectButtonClick, visible: true }],
[this._editId, { cssClass: this._config.editButtonClass, defaultText: this._editId, handler: this._onEditButtonClick, visible: true }],
[this._deleteId, { cssClass: this._config.deleteButtonClass, defaultText: this._deleteId, handler: this._onDeleteButtonClick, visible: true }],
];
const targetDescriptions = buttons.map(b => descriptions.find(d => d[0] === b));
this._descriptors = new Map(targetDescriptions);
this._floatingToolbarElementHandler = new FloatingToolbarElementHandler(this._canvasElementHandler, this._viewer, this._config.cssClass, this._config.bigButtonCssClass);
this._floatingToolbarElementHandler.init(this._descriptors);
}
// TODO: there is no time to make it good now.
// Unfortunately, we have a terrible init process.
// In this case canvas must have his own eventManager and Viewer Event Manager must be as proxy, I think.
set eventManager(eventManager) {
this._eventManager = eventManager;
this._eventManager.addSelectedItemChanged(this._onSelectedItemChanged);
this._eventManager.addItemChanging(this._updateView);
this._eventManager.addIsEditingChanged(this._fullUpdate);
this._eventManager.addItemPropertyChanged(this._onItemPropertyChanged);
this._canvas.add_zoomChanged(this._updatePosition);
this._eventManager.addItemHandlerHover(this._onItemHandlerHover);
this._eventManager.addDndStarted(this._onDndStarted);
this._eventManager.addDndFinished(this._onDndFinished);
}
_getPositionMode(handler) {
const angle = handler === null || handler === void 0 ? void 0 : handler.rectangle.angle;
return (this._config.mode === FloatingToolbarMode.Inside &&
isImageOrPlaceholder(handler) &&
(EqualsOfFloatNumbers(angle % 90, 0) || EqualsOfFloatNumbers(angle, 360))) ?
UpdatePositionMode.Center :
UpdatePositionMode.Smart;
}
get _defaultConfig() {
return {
enabled: true,
mode: FloatingToolbarMode.Classic,
buttons: [this._selectId, this._editId, this._deleteId]
};
}
get enabled() {
return this._config.enabled;
}
set enabled(v) {
if (v === this._config.enabled)
return;
this._config.enabled = v;
this._floatingToolbarElementHandler.changeVisibility(v);
}
get _isShowFloatingItemToolbar() {
if (this._dndIsInProgress)
return false;
const handler = this._currentHandlerItem;
if (handler == null ||
!this._config.enabled ||
!this._canvas.viewer.inputHandlerManager.isDefault ||
!handler.isVisible() ||
handler.isLocked())
return false;
const isModifyHandlerOperation = this._selectionHandler.isDragging || this._selectionHandler.isResizing || this._selectionHandler.isRotating;
if (isModifyHandlerOperation)
return false;
if (this._canvas.contentEditingPlaceholderItemHandler != null)
return false;
return !(this._canvas.autoPlaceholderEditModeEnabled && isPlaceholder(handler));
}
dispose() {
var _a, _b, _c, _d, _e, _f;
(_a = this._floatingToolbarElementHandler) === null || _a === void 0 ? void 0 : _a.dispose();
(_b = this._eventManager) === null || _b === void 0 ? void 0 : _b.removeSelectedItemChanged(this._onSelectedItemChanged);
(_c = this._eventManager) === null || _c === void 0 ? void 0 : _c.removeItemChanging(this._updateView);
(_d = this._eventManager) === null || _d === void 0 ? void 0 : _d.removeIsEditingChanged(this._fullUpdate);
(_e = this._eventManager) === null || _e === void 0 ? void 0 : _e.removeItemPropertyChanged(this._onItemPropertyChanged);
this._canvas.remove_zoomChanged(this._updatePosition);
(_f = this._eventManager) === null || _f === void 0 ? void 0 : _f.removeItemHandlerHover(this._onItemHandlerHover);
this._eventManager.removeDndStarted(this._onDndStarted);
this._eventManager.removeDndFinished(this._onDndFinished);
}
}
/**
* Floating Toolbar modes.
* @public
*/
export var FloatingToolbarMode;
(function (FloatingToolbarMode) {
/** Displays the toolbar on the canvas regardless of user hover. */
FloatingToolbarMode["Classic"] = "Classic";
/** Displays the toolbar on top of images and image placeholders when the user hovers over the item. */
FloatingToolbarMode["Inside"] = "Inside";
})(FloatingToolbarMode || (FloatingToolbarMode = {}));
//# sourceMappingURL=FloatingToolbarManager.js.map