@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
359 lines • 19.4 kB
JavaScript
import { PointF, getTriangleAngle, normalizeAngle, EqualsOfFloatNumbers } from "@aurigma/design-atoms-model/Math";
import { ArgumentException } from "@aurigma/design-atoms-model/Exception";
import { SelectionState, SelectionHandler } from "./SelectionHandler";
import { EventObject } from "@aurigma/design-atoms-model/EventObject";
import { GroupItemHandler } from "../../ItemHandlers/GroupItemHandler";
var SelectionRectangleHandler = /** @class */ (function () {
function SelectionRectangleHandler(_selectionModifier) {
var _this = this;
if (_selectionModifier === void 0) { _selectionModifier = null; }
this._selectionModifier = _selectionModifier;
this._cumulativeDelta = new PointF(0, 0);
this._resizeIndex = null;
this._resizeOrigin = null;
this._allowNegativeResize = null;
this._itemHandlerResizeStartRects = null;
this._state = SelectionState.Idle;
this.startMovingByPoint = function (startPoint, startRectangle) {
_this._checkStartArguments("startMovingByPoint");
_this._setStartParams(startRectangle, startPoint);
_this._setState(SelectionState.Drag);
};
this.updateMovingByPoint = function (args) {
var _a, _b, _c, _d, _e;
_this._checkUpdateArguments("updateMove", SelectionState.Drag, args.finished);
var point = args.point, finished = args.finished;
var lastPoint = (_a = _this._lastPoint) !== null && _a !== void 0 ? _a : _this._startPoint;
var delta = new PointF(point.x - _this._startPoint.x, point.y - _this._startPoint.y);
if (((_b = _this._selectionModifier) === null || _b === void 0 ? void 0 : _b.beforeMovePerformed) != null) {
var momentDelta = new PointF(point.x - lastPoint.x, point.y - lastPoint.y);
var args_1 = {
delta: delta,
momentDelta: momentDelta,
startPoint: _this._startPoint,
startRectangle: _this._startRectangle
};
delta = (_c = _this._selectionModifier) === null || _c === void 0 ? void 0 : _c.beforeMovePerformed(args_1);
}
var targetMomentDelta = new PointF(_this._startPoint.x + delta.x - lastPoint.x, _this._startPoint.y + delta.y - lastPoint.y);
if (!((_d = args.allowMoveHorizontal) !== null && _d !== void 0 ? _d : true))
targetMomentDelta.x = 0;
if (!((_e = args.allowMoveVertical) !== null && _e !== void 0 ? _e : true))
targetMomentDelta.y = 0;
_this._lastPoint = new PointF(lastPoint.x + targetMomentDelta.x, lastPoint.y + targetMomentDelta.y);
var r = _this._rectangle.clone();
r.centerX = _this._rectangle.centerX + targetMomentDelta.x;
r.centerY = _this._rectangle.centerY + targetMomentDelta.y;
_this._updateRectangle(r, finished);
_this._rectangleCenterChanged.notify({ delta: targetMomentDelta.clone(), finished: finished });
};
this.startResizingByPoint = function (startPoint, startRectangle, resizeIndex, allowNegativeResize, itemHandlers) {
_this._checkStartArguments("startResizingByPoint");
if (resizeIndex == null || allowNegativeResize == null) {
_this._reset();
throw new ArgumentException("SelectionRectangleHandler.startResize: resizeIndex and allowNegativeResize cannot be null!");
}
_this._resizeIndex = resizeIndex;
_this._allowNegativeResize = allowNegativeResize;
_this._setStartParams(startRectangle, startPoint);
_this._setState(SelectionState.Resize);
var origin = new PointF(_this._startRectangle.center.x - (SelectionHandler.cw[_this._resizeIndex] * _this._startRectangle.width / 2), _this._startRectangle.center.y - (SelectionHandler.ch[_this._resizeIndex] * _this._startRectangle.height / 2));
_this._resizeOrigin = origin.rotateAt(_this._startRectangle.angle, _this._startRectangle.center);
_this._itemHandlerResizeStartRects = _this._getItemHandlersRects(itemHandlers);
};
this._setState = function (state) {
if (_this._state === state)
return;
_this._state = state;
_this._stateChanged.notify(state);
};
this._reset = function () {
_this._lastPoint = null;
_this._startPoint = null;
_this._startRectangle = null;
_this._resizeIndex = null;
_this._resizeOrigin = null;
_this._cumulativeDelta.x = 0;
_this._cumulativeDelta.y = 0;
_this._setState(SelectionState.Idle);
};
this._rectangleChanged = new EventObject();
this._rectangleAngleChanged = new EventObject();
this._rectangleResized = new EventObject();
this._rectangleCenterChanged = new EventObject();
this._stateChanged = new EventObject();
this._checkStartArguments = function (methodName) {
try {
if (_this._state !== SelectionState.Idle)
throw new ArgumentException("SelectionRectangleHandler." + methodName + ": cannot start operation because " + SelectionState[_this._state] + " operation is in progress!");
}
catch (ex) {
_this._reset();
throw ex;
}
};
this._checkUpdateArguments = function (methodName, state, finished) {
try {
if (_this._rectangle == null)
throw new ArgumentException("SelectionRectangleHandler." + methodName + ": rectangle must be defined");
if (_this._startRectangle == null || _this._state !== state)
throw new ArgumentException("SelectionRectangleHandler." + methodName + ": " + SelectionState[_this._state] + " operation haven't started");
if (finished && _this._state === SelectionState.Idle)
throw new ArgumentException("SelectionRectangleHandler." + methodName + ": " + SelectionState[SelectionState.Idle] + " cannot be finished");
}
catch (ex) {
_this._reset();
throw ex;
}
};
}
Object.defineProperty(SelectionRectangleHandler.prototype, "rectangle", {
get: function () {
return this._rectangle;
},
enumerable: true,
configurable: true
});
SelectionRectangleHandler.prototype.startRotatingByPoint = function (startPoint, startRectangle) {
this._checkStartArguments("startRotatingByPoint");
this._setStartParams(startRectangle, startPoint);
this._setState(SelectionState.Rotate);
};
SelectionRectangleHandler.prototype.updateRotatingByPoint = function (params) {
var _a;
this._checkUpdateArguments("updateRotation", SelectionState.Rotate, params.finished);
var point = params.point, tolerance = params.tolerance, rotationStep = params.rotationStep, finished = params.finished;
var p1 = point.clone(), p2 = this._startPoint.clone(), r = this._rectangle.clone(), p3 = new PointF(r.centerX, r.centerY), angle = getTriangleAngle(p1, p2, p3);
if (EqualsOfFloatNumbers(angle, 0))
return;
angle = normalizeAngle(this._startRectangle.angle + angle);
var newAngle = angle;
var mod = angle % rotationStep;
if (mod < tolerance) {
newAngle = rotationStep * Math.floor(angle / rotationStep);
}
else if (mod > rotationStep - tolerance) {
newAngle = rotationStep * Math.floor(angle / rotationStep + 1);
}
r.angle = normalizeAngle(newAngle);
if (((_a = this._selectionModifier) === null || _a === void 0 ? void 0 : _a.beforeRotatePerformed) != null) {
var data = {
currentRect: r,
previousRectangle: this._rectangle
};
r = this._selectionModifier.beforeRotatePerformed(data);
}
var args = {
angle: r.angle - this._rectangle.angle,
origin: r.center,
finished: finished
};
this._updateRectangle(r, finished);
this._rectangleAngleChanged.notify(args);
};
SelectionRectangleHandler.prototype._getItemHandlersRects = function (itemHandlers) {
var result = [];
var getHandlerRect = function (handler) {
result.push({ itemType: handler.item.type, startRectangle: handler.rectangle });
};
itemHandlers.forEach(function (handler) {
if (handler instanceof GroupItemHandler)
handler.getNestedItemHandlers(true).forEach(getHandlerRect);
else
getHandlerRect(handler);
});
return result;
};
SelectionRectangleHandler.prototype.updateResizingByPoint = function (args, itemHandlers) {
if (itemHandlers === void 0) { itemHandlers = null; }
var _a;
this._checkUpdateArguments("updateResize", SelectionState.Resize, args.finished);
var point = args.point, arbitraryResize = args.arbitraryResize, finished = args.finished;
if (point == null) {
point = this._lastPoint;
}
this._lastPoint = point;
var startRect = this._startRectangle;
var t, r = this._rectangle.clone();
// new width or height, depends on resize action
var newDem = new PointF(point.x - startRect.centerX, point.y - startRect.centerY);
newDem.rotate(-r.angle);
// old width or height, depends on resize action
var oldDem = new PointF(this._startPoint.x - startRect.centerX, this._startPoint.y - startRect.centerY);
oldDem.rotate(-r.angle);
// added width or height, depends on resize action
var addedDem = newDem.translate(-oldDem.x, -oldDem.y);
//word interpretation of gripses (movable anchors)
var gripsDict = { left: 6, top: 5 };
// 1 or -1 (for choosing plus or minus action)
var signMultiplierX = 1;
var signMultiplierY = 1;
if (!arbitraryResize) {
var dx = addedDem.x * SelectionHandler.cw[this._resizeIndex] / startRect.width;
var dy = addedDem.y * SelectionHandler.ch[this._resizeIndex] / startRect.height;
var d = dx < dy ? dx : dy;
addedDem.x = startRect.width * d;
addedDem.y = startRect.height * d;
r.width = startRect.width + addedDem.x;
r.height = startRect.height + addedDem.y;
}
else {
r.width = startRect.width + addedDem.x * SelectionHandler.cw[this._resizeIndex];
r.height = startRect.height + addedDem.y * SelectionHandler.ch[this._resizeIndex];
if (this._resizeIndex === gripsDict["left"] ||
this._resizeIndex === gripsDict["top"]) {
signMultiplierX = -1;
signMultiplierY = -1;
}
if (this._resizeIndex === 1) {
signMultiplierX = -1;
signMultiplierY = -1;
}
if (this._resizeIndex === 2) {
signMultiplierX = 1;
signMultiplierY = -1;
}
if (this._resizeIndex === 4) {
signMultiplierX = -1;
signMultiplierY = 1;
}
}
if (this._allowNegativeResize || r.width >= 0 && r.height >= 0) {
t = new PointF(addedDem.x / 2 * SelectionHandler.cw[this._resizeIndex], addedDem.y / 2 * SelectionHandler.ch[this._resizeIndex]);
t.rotate(r.angle);
r.centerX = startRect.centerX + (t.x * signMultiplierX);
r.centerY = startRect.centerY + (t.y * signMultiplierY);
if (arbitraryResize) {
var oldCenter = t = new PointF(startRect.centerX, startRect.centerY);
oldCenter.rotate(-r.angle);
oldCenter.x =
oldCenter.x +
addedDem.x /
2 *
SelectionHandler.cw[this._resizeIndex] *
SelectionHandler.cw[this._resizeIndex]; //signMultiplierX;
oldCenter.y =
oldCenter.y +
addedDem.y /
2 *
SelectionHandler.ch[this._resizeIndex] *
SelectionHandler.ch[this._resizeIndex]; //signMultiplierY;
oldCenter.rotate(r.angle);
r.centerX = oldCenter.x;
r.centerY = oldCenter.y;
}
}
else {
var newCenter = new PointF((-SelectionHandler.cw[this._resizeIndex] * this._rectangle.width) / 2, (-SelectionHandler.ch[this._resizeIndex] * this._rectangle.height) / 2);
newCenter.rotate(this._rectangle.angle);
newCenter.translate(this._rectangle.centerX, this._rectangle.centerY);
r.center = newCenter;
if (!arbitraryResize) {
// should keep proportions
var widthToHeightRate = startRect.width / startRect.height;
if (widthToHeightRate >= 1) {
r.width = Math.max(r.width, 1 * widthToHeightRate);
r.height = Math.max(r.height, 1);
}
else {
r.width = Math.max(r.width, 1);
r.height = Math.max(r.height, 1 / widthToHeightRate);
}
}
else {
r.width = Math.max(r.width, 1);
r.height = Math.max(r.height, 1);
}
var diff = new PointF((SelectionHandler.cw[this._resizeIndex] * r.width) / 2, (SelectionHandler.ch[this._resizeIndex] * r.height) / 2);
diff.rotate(r.angle);
r.centerX += diff.x;
r.centerY += diff.y;
}
if (((_a = this._selectionModifier) === null || _a === void 0 ? void 0 : _a.beforeResizePerformed) != null) {
var data = {
arbitraryResize: args.arbitraryResize,
currentRect: r,
previousRectangle: this._rectangle,
resizeIndex: args.resizeIndex,
startRectangle: this._startRectangle,
startItemHandlersRects: this._itemHandlerResizeStartRects,
rectangleItemHandlers: itemHandlers
};
r = this._selectionModifier.beforeResizePerformed(data);
}
if (EqualsOfFloatNumbers(r.width, 0))
r.width = 1;
if (EqualsOfFloatNumbers(r.height, 0))
r.height = 1;
var scaleX = r.width / this._rectangle.width;
var scaleY = r.height / this._rectangle.height;
var eventArgs = {
finished: finished,
origin: this._resizeOrigin,
scaleX: scaleX,
scaleY: scaleY,
angle: r.angle
};
this._updateRectangle(r, finished);
this._rectangleResized.notify(eventArgs);
};
SelectionRectangleHandler.prototype.startMove = function (startRectangle) {
this._checkStartArguments("startMove");
this._setStartParams(startRectangle, null);
this._setState(SelectionState.Drag);
};
SelectionRectangleHandler.prototype.move = function (params) {
var _a, _b, _c, _d;
this._checkUpdateArguments("move", SelectionState.Drag, params.finished);
this._cumulativeDelta.x += params.delta.x;
this._cumulativeDelta.y += params.delta.y;
if (((_a = this._selectionModifier) === null || _a === void 0 ? void 0 : _a.beforeMovePerformed) != null) {
var args = {
delta: this._cumulativeDelta,
momentDelta: params.delta,
startPoint: this._startPoint,
startRectangle: this._startRectangle
};
this._cumulativeDelta = (_b = this._selectionModifier) === null || _b === void 0 ? void 0 : _b.beforeMovePerformed(args);
}
if (!((_c = params.allowMoveHorizontal) !== null && _c !== void 0 ? _c : true))
this._cumulativeDelta.x = 0;
if (!((_d = params.allowMoveVertical) !== null && _d !== void 0 ? _d : true))
this._cumulativeDelta.y = 0;
var r = this._rectangle.clone();
if (!params.finished) {
r.centerX = this._startRectangle.centerX + this._cumulativeDelta.x;
r.centerY = this._startRectangle.centerY + this._cumulativeDelta.y;
}
var correctedDelta = new PointF((r.centerX - this._rectangle.centerX), (r.centerY - this._rectangle.centerY));
this._updateRectangle(r, params.finished);
this._rectangleCenterChanged.notify({ delta: correctedDelta, finished: params.finished });
};
SelectionRectangleHandler.prototype._updateRectangle = function (rectangle, finished) {
this._rectangle = rectangle;
var args = { rectangle: rectangle, finished: finished };
this._rectangleChanged.notify(args);
if (finished) {
this._reset();
}
};
SelectionRectangleHandler.prototype.addRectangleChanged = function (handler) { this._rectangleChanged.add(handler); };
SelectionRectangleHandler.prototype.removeRectangleChanged = function (handler) { this._rectangleChanged.remove(handler); };
SelectionRectangleHandler.prototype.addRectangleAngleChanged = function (handler) { this._rectangleAngleChanged.add(handler); };
SelectionRectangleHandler.prototype.removeRectangleAngleChanged = function (handler) { this._rectangleAngleChanged.remove(handler); };
SelectionRectangleHandler.prototype.addRectangleResized = function (handler) { this._rectangleResized.add(handler); };
SelectionRectangleHandler.prototype.removeRectangleResized = function (handler) { this._rectangleResized.remove(handler); };
SelectionRectangleHandler.prototype.addRectangleMoved = function (handler) { this._rectangleCenterChanged.add(handler); };
SelectionRectangleHandler.prototype.removeRectangleMoved = function (handler) { this._rectangleCenterChanged.remove(handler); };
SelectionRectangleHandler.prototype.addStateChanged = function (handler) { this._stateChanged.add(handler); };
SelectionRectangleHandler.prototype.removeStateChanged = function (handler) { this._stateChanged.remove(handler); };
SelectionRectangleHandler.prototype._setStartParams = function (startRectangle, startPoint) {
this._rectangle = startRectangle;
this._startRectangle = startRectangle;
if (startPoint != null)
this._startPoint = startPoint;
};
return SelectionRectangleHandler;
}());
export { SelectionRectangleHandler };
//# sourceMappingURL=SelectionRectangleHandler.js.map