Refactor relationship.

This commit is contained in:
Paulo Gustavo Veiga 2022-11-26 08:47:35 -08:00
parent 4be63fee4d
commit c1dc4554d7
8 changed files with 390 additions and 379 deletions

View File

@ -21,7 +21,7 @@ import { $assert } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d'; import Point from '@wisemapping/web2d';
import { Mindmap } from '..'; import { Mindmap } from '..';
import CommandContext from './CommandContext'; import CommandContext from './CommandContext';
import ControlPoint from './ControlPoint'; import RelationshipControlPoints from './RelationshipControlPoints';
import Events from './Events'; import Events from './Events';
import NodeModel from './model/NodeModel'; import NodeModel from './model/NodeModel';
import RelationshipModel from './model/RelationshipModel'; import RelationshipModel from './model/RelationshipModel';
@ -57,7 +57,7 @@ abstract class ActionDispatcher extends Events {
abstract moveTopic(topicId: number, position: Point): void; abstract moveTopic(topicId: number, position: Point): void;
abstract moveControlPoint(ctrlPoint: ControlPoint, point: Point): void; abstract moveControlPoint(ctrlPoint: RelationshipControlPoints, point: Point): void;
abstract changeFontFamilyToTopic(topicIds: number[], fontFamily: string): void; abstract changeFontFamilyToTopic(topicIds: number[], fontFamily: string): void;

View File

@ -1,250 +0,0 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Elipse, Line, Point } from '@wisemapping/web2d';
import { $defined } from '@wisemapping/core-js';
import Shape from './util/Shape';
import ActionDispatcher from './ActionDispatcher';
import Workspace from './Workspace';
import PositionType from './PositionType';
class ControlPoint {
private control1: Elipse;
private control2: Elipse;
private _controlPointsController: Elipse[];
private _controlLines: Line[];
private _isBinded: boolean;
_line: Line;
private _workspace: Workspace;
private _endPoint: PositionType[];
private _orignalCtrlPoint: PositionType[];
private _controls: PositionType[];
private _mouseMoveFunction: (e: MouseEvent) => void;
private _mouseUpFunction: (e: MouseEvent) => void;
constructor() {
this.control1 = new Elipse({
width: 6,
height: 6,
stroke: '1 solid #6589de',
fillColor: 'gray',
visibility: false,
});
this.control1.setCursor('pointer');
this.control2 = new Elipse({
width: 6,
height: 6,
stroke: '1 solid #6589de',
fillColor: 'gray',
visibility: false,
});
this.control2.setCursor('pointer');
this._controlPointsController = [this.control1, this.control2];
this._controlLines = [
new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }),
new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }),
];
this._isBinded = false;
this._controlPointsController[0].addEvent('mousedown', (event: MouseEvent) => {
this._mouseDown(event, ControlPoint.FROM);
});
this._controlPointsController[0].addEvent('click', (event: MouseEvent) => {
this._mouseClick(event);
});
this._controlPointsController[0].addEvent('dblclick', (event: MouseEvent) => {
this._mouseClick(event);
});
this._controlPointsController[1].addEvent('mousedown', (event: MouseEvent) => {
this._mouseDown(event, ControlPoint.TO);
});
this._controlPointsController[1].addEvent('click', (event: MouseEvent) => {
this._mouseClick(event);
});
this._controlPointsController[1].addEvent('dblclick', (event: MouseEvent) => {
this._mouseClick(event);
});
}
setLine(line: Line) {
if ($defined(this._line)) {
this._removeLine();
}
this._line = line;
this._createControlPoint();
this._endPoint = [];
this._orignalCtrlPoint = [];
[this._orignalCtrlPoint[0], this._orignalCtrlPoint[1]] = this._controls;
this._endPoint[0] = { ...this._line.getLine().getFrom() };
this._endPoint[1] = { ...this._line.getLine().getTo() };
}
setControlPointTestId(ctrlPoint1, ctrlPoint2) {
this.control1.setTestId(ctrlPoint1);
this.control2.setTestId(ctrlPoint2);
}
redraw() {
if ($defined(this._line)) this._createControlPoint();
}
private _createControlPoint() {
this._controls = this._line.getLine().getControlPoints();
let pos = this._line.getLine().getFrom();
this._controlPointsController[0].setPosition(
this._controls[ControlPoint.FROM].x + pos.x,
this._controls[ControlPoint.FROM].y + pos.y - 3,
);
this._controlLines[0].setFrom(pos.x, pos.y);
this._controlLines[0].setTo(
this._controls[ControlPoint.FROM].x + pos.x + 3,
this._controls[ControlPoint.FROM].y + pos.y,
);
pos = this._line.getLine().getTo();
this._controlLines[1].setFrom(pos.x, pos.y);
this._controlLines[1].setTo(
this._controls[ControlPoint.TO].x + pos.x + 3,
this._controls[ControlPoint.TO].y + pos.y,
);
this._controlPointsController[1].setPosition(
this._controls[ControlPoint.TO].x + pos.x,
this._controls[ControlPoint.TO].y + pos.y - 3,
);
}
private _removeLine() {
// Overwrite default behaviour ...
}
private _mouseDown(event: MouseEvent, point: number) {
if (!this._isBinded) {
this._isBinded = true;
this._mouseMoveFunction = (e) => {
this._mouseMoveEvent(e, point);
};
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
this._mouseUpFunction = (e: MouseEvent) => {
this._mouseUp(e, MouseEvent);
};
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
}
event.preventDefault();
event.stopPropagation();
return false;
}
private _mouseMoveEvent(event: MouseEvent, point: Point) {
const screen = this._workspace.getScreenManager();
const pos = screen.getWorkspaceMousePosition(event);
let cords;
if (point === 0) {
cords = Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos);
this._line.setFrom(cords.x, cords.y);
this._line.setSrcControlPoint(new Point(pos.x - cords.x, pos.y - cords.y));
} else {
cords = Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos);
this._line.setTo(cords.x, cords.y);
this._line.setDestControlPoint(new Point(pos.x - cords.x, pos.y - cords.y));
}
this._controls[point].x = pos.x - cords.x;
this._controls[point].y = pos.y - cords.y;
this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3);
this._controlLines[point].setFrom(cords.x, cords.y);
this._controlLines[point].setTo(pos.x - 2, pos.y);
this._line.getLine().updateLine(point);
}
private _mouseUp(event: MouseEvent, point: Point) {
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
const actionDispatcher = ActionDispatcher.getInstance();
actionDispatcher.moveControlPoint(this, point);
this._isBinded = false;
}
_mouseClick(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
return false;
}
setVisibility(visible: boolean) {
if (visible) {
this._controlLines[0].moveToFront();
this._controlLines[1].moveToFront();
this._controlPointsController[0].moveToFront();
this._controlPointsController[1].moveToFront();
}
this._controlPointsController[0].setVisibility(visible);
this._controlPointsController[1].setVisibility(visible);
this._controlLines[0].setVisibility(visible);
this._controlLines[1].setVisibility(visible);
}
addToWorkspace(workspace: Workspace): void {
this._workspace = workspace;
workspace.append(this._controlPointsController[0]);
workspace.append(this._controlPointsController[1]);
workspace.append(this._controlLines[0]);
workspace.append(this._controlLines[1]);
}
removeFromWorkspace(workspace: Workspace) {
this._workspace!;
workspace.removeChild(this._controlPointsController[0]);
workspace.removeChild(this._controlPointsController[1]);
workspace.removeChild(this._controlLines[0]);
workspace.removeChild(this._controlLines[1]);
}
getControlPoint(index: number): PositionType {
return this._controls[index];
}
getOriginalEndPoint(index: number): PositionType {
return this._endPoint[index];
}
getOriginalCtrlPoint(index: number): PositionType {
return this._orignalCtrlPoint[index];
}
static FROM = 0;
static TO = 1;
}
export default ControlPoint;

View File

@ -18,7 +18,7 @@
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import { Arrow, Point, ElementClass } from '@wisemapping/web2d'; import { Arrow, Point, ElementClass } from '@wisemapping/web2d';
import ConnectionLine from './ConnectionLine'; import ConnectionLine from './ConnectionLine';
import ControlPoint from './ControlPoint'; import RelationshipControlPoints from './RelationshipControlPoints';
import RelationshipModel from './model/RelationshipModel'; import RelationshipModel from './model/RelationshipModel';
import PositionType from './PositionType'; import PositionType from './PositionType';
import Topic from './Topic'; import Topic from './Topic';
@ -32,7 +32,7 @@ class Relationship extends ConnectionLine {
private _isInWorkspace: boolean; private _isInWorkspace: boolean;
private _controlPointsController: ControlPoint; private _controlPointsController: RelationshipControlPoints;
private _startArrow: Arrow; private _startArrow: Arrow;
@ -68,7 +68,7 @@ class Relationship extends ConnectionLine {
this._focusShape.setVisibility(false); this._focusShape.setVisibility(false);
this._onFocus = false; this._onFocus = false;
this._isInWorkspace = false; this._isInWorkspace = false;
this._controlPointsController = new ControlPoint(); this._controlPointsController = new RelationshipControlPoints(this);
this._startArrow = new Arrow(); this._startArrow = new Arrow();
this._startArrow.setStrokeColor(strokeColor); this._startArrow.setStrokeColor(strokeColor);
@ -83,17 +83,12 @@ class Relationship extends ConnectionLine {
} }
// Position the line ... // Position the line ...
if ($defined(model.getSrcCtrlPoint())) { if (model.getSrcCtrlPoint()) {
const srcPoint = { ...model.getSrcCtrlPoint() }; const srcPoint = { ...model.getSrcCtrlPoint() };
this.setSrcControlPoint(srcPoint); this.setSrcControlPoint(srcPoint);
// Set test id in control point
this._controlPointsController.setControlPointTestId(
`control-${Math.abs(srcPoint.x)}`,
`control-${Math.abs(srcPoint.y)}`,
);
} }
if ($defined(model.getDestCtrlPoint())) {
if (model.getDestCtrlPoint()) {
const destPoint = { ...model.getDestCtrlPoint() }; const destPoint = { ...model.getDestCtrlPoint() };
this.setDestControlPoint(destPoint); this.setDestControlPoint(destPoint);
} }
@ -149,9 +144,10 @@ class Relationship extends ConnectionLine {
this._positionateConnector(targetTopic); this._positionateConnector(targetTopic);
if (this.isOnFocus()) { if (this.isOnFocus()) {
this._refreshShape(); this.refreshShape();
} }
this._focusShape.moveToBack(); this._focusShape.moveToBack();
this._controlPointsController.redraw(); this._controlPointsController.redraw();
} }
@ -213,12 +209,13 @@ class Relationship extends ConnectionLine {
removeFromWorkspace(workspace: Workspace): void { removeFromWorkspace(workspace: Workspace): void {
workspace.removeChild(this._focusShape); workspace.removeChild(this._focusShape);
workspace.removeChild(this._controlPointsController); workspace.removeChild(this._controlPointsController);
if (!workspace.isReadOnly) {
this._line2d.removeEvent('click', this._controlPointControllerListener); this._line2d.removeEvent('click', this._controlPointControllerListener);
}
this._isInWorkspace = false; this._isInWorkspace = false;
workspace.removeChild(this._startArrow); workspace.removeChild(this._startArrow);
if (this._endArrow) workspace.removeChild(this._endArrow); if (this._endArrow) {
workspace.removeChild(this._endArrow);
}
super.removeFromWorkspace(workspace); super.removeFromWorkspace(workspace);
} }
@ -231,18 +228,17 @@ class Relationship extends ConnectionLine {
// Change focus shape // Change focus shape
if (this.isOnFocus() !== focus) { if (this.isOnFocus() !== focus) {
if (focus) { if (focus) {
this._refreshShape(); this.refreshShape();
this._controlPointsController.setLine(this);
} }
this._focusShape.setVisibility(focus);
this._focusShape.setVisibility(focus);
this._controlPointsController.setVisibility(focus); this._controlPointsController.setVisibility(focus);
this._onFocus = focus; this._onFocus = focus;
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this); this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
} }
} }
private _refreshShape(): void { refreshShape(): void {
const sPos = this._line2d.getFrom(); const sPos = this._line2d.getFrom();
const tPos = this._line2d.getTo(); const tPos = this._line2d.getTo();
const ctrlPoints = this._line2d.getControlPoints(); const ctrlPoints = this._line2d.getControlPoints();
@ -253,6 +249,7 @@ class Relationship extends ConnectionLine {
shapeCtrlPoints[0].y = ctrlPoints[0].y; shapeCtrlPoints[0].y = ctrlPoints[0].y;
shapeCtrlPoints[1].x = ctrlPoints[1].x; shapeCtrlPoints[1].x = ctrlPoints[1].x;
shapeCtrlPoints[1].y = ctrlPoints[1].y; shapeCtrlPoints[1].y = ctrlPoints[1].y;
this._focusShape.updateLine(); this._focusShape.updateLine();
} }

View File

@ -0,0 +1,289 @@
/*
* Copyright [2021] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// eslint-disable-next-line max-classes-per-file
import { Elipse, Line } from '@wisemapping/web2d';
import Shape from './util/Shape';
import ActionDispatcher from './ActionDispatcher';
import Workspace from './Workspace';
import PositionType from './PositionType';
import Relationship from './Relationship';
enum PivotType {
Start = 0,
End = 1,
}
class ControlPivotLine {
private _dot: Elipse;
private _line: Line;
private _pivotType: PivotType;
private _workspace: Workspace;
private _relationship: Relationship;
private _changeHander: () => void;
private _moveRelHandler: (
relationPosition: PositionType,
controlPointPosition: PositionType,
) => void;
private _isVisible: boolean;
private _mouseMoveHandler: (e: MouseEvent) => void;
private _mousedUpHandler: () => void;
constructor(
pivotType: PivotType,
relationship: Relationship,
mouseMoveHandler: (relationPosition: PositionType, controlPointPosition: PositionType) => void,
changeHander: () => void,
) {
this._pivotType = pivotType;
this._changeHander = changeHander;
this._moveRelHandler = mouseMoveHandler;
this._relationship = relationship;
// Build dot controller ...
this._dot = new Elipse({
width: 6,
height: 6,
stroke: '1 solid #6589de',
fillColor: 'gray',
visibility: false,
});
this._dot.setCursor('pointer');
// Build line ...
this._line = new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 });
// Register events ...
this._dot.addEvent('mousedown', (event: MouseEvent) => {
this._mouseDown(event);
});
const mouseClick = (event: MouseEvent): boolean => {
event.preventDefault();
event.stopPropagation();
return false;
};
this._dot.addEvent('click', mouseClick);
this._dot.addEvent('dblclick', mouseClick);
// Register handled ...
this._mouseMoveHandler = (e: MouseEvent) => this.mouseMoveHandler(e);
this._mousedUpHandler = () => this._mouseUpHandler();
}
private _mouseDown(event: MouseEvent) {
this.getWorkspace().getScreenManager().addEvent('mousemove', this._mouseMoveHandler);
this.getWorkspace().getScreenManager().addEvent('mouseup', this._mousedUpHandler);
event.preventDefault();
event.stopPropagation();
return false;
}
setVisibility(value: boolean) {
this._isVisible = value;
const screenManager = this.getWorkspace().getScreenManager();
if (!value) {
screenManager.removeEvent('mousemove', this._mouseMoveHandler);
screenManager.removeEvent('mouseup', this._mouseUpHandler);
}
// Make it visible ...
this._dot.setVisibility(value);
this._line.setVisibility(value);
if (value) {
this.redraw();
this._line.moveToFront();
this._dot.moveToFront();
}
}
getPosition(): PositionType {
const line = this._relationship.getLine();
return line.getControlPoints()[this._pivotType];
}
redraw(): void {
if (this._isVisible) {
const relationshipLine = this._relationship.getLine();
const startPosition =
this._pivotType === PivotType.Start ? relationshipLine.getTo() : relationshipLine.getFrom();
const ctrPosition = relationshipLine.getControlPoints()[this._pivotType];
this._line.setFrom(startPosition.x, startPosition.y);
this._line.setTo(startPosition.x - ctrPosition.x - 5, startPosition.y - ctrPosition.y - 5);
this._dot.setPosition(
startPosition.x - ctrPosition.x - 8,
startPosition.y - ctrPosition.y - 8,
);
}
}
private mouseMoveHandler(event: MouseEvent) {
const screen = this._workspace.getScreenManager();
const mousePosition = screen.getWorkspaceMousePosition(event);
// Update relatioship position ...
let relationshipPosition: PositionType;
console.log(this._pivotType);
if (this._pivotType === PivotType.Start) {
relationshipPosition = Shape.calculateRelationShipPointCoordinates(
this._relationship.getSourceTopic(),
mousePosition,
);
this._moveRelHandler(relationshipPosition, {
x: mousePosition.x - relationshipPosition.x,
y: mousePosition.y - relationshipPosition.y,
});
} else {
relationshipPosition = Shape.calculateRelationShipPointCoordinates(
this._relationship.getTargetTopic(),
mousePosition,
);
this._moveRelHandler(relationshipPosition, {
x: mousePosition.x - relationshipPosition.x,
y: mousePosition.y - relationshipPosition.y,
});
}
// Update pivot ...
this._dot.setPosition(mousePosition.x - 5, mousePosition.y - 3);
this._line.setTo(mousePosition.x - 2, mousePosition.y);
// Update controller ...
this._relationship.getLine().updateLine(this._pivotType);
}
private _mouseUpHandler() {
const screenManager = this.getWorkspace().getScreenManager();
screenManager.removeEvent('mousemove', this._mouseMoveHandler);
screenManager.removeEvent('mouseup', this._mouseUpHandler);
this._changeHander();
}
addToWorkspace(workspace: Workspace): void {
this._workspace = workspace;
workspace.append(this._line);
workspace.append(this._dot);
}
removeFromWorkspace(workspace: Workspace) {
// Hide all elements ...
this.setVisibility(false);
// Remove elements ...
workspace.removeChild(this._line);
workspace.removeChild(this._dot);
}
private getWorkspace(): Workspace {
return this._workspace!;
}
}
class RelationshipControlPoints {
// Visual element ...
private _pivotLines: [ControlPivotLine, ControlPivotLine];
private _relationship: Relationship;
private _relationshipLinePositions: [PositionType, PositionType];
constructor(relationship: Relationship) {
this._relationship = relationship;
const startControlLine = new ControlPivotLine(
PivotType.Start,
relationship,
(relationPosition, controlPointPosition) => {
const line = this._relationship.getLine();
line.setFrom(relationPosition.x, relationPosition.y);
line.setSrcControlPoint(controlPointPosition);
console.log(JSON.stringify(controlPointPosition));
},
() => {
const actionDispatcher = ActionDispatcher.getInstance();
actionDispatcher.moveControlPoint(this, PivotType.Start);
relationship.setOnFocus(true);
},
);
const endControlLine = new ControlPivotLine(
PivotType.End,
relationship,
(relationPosition, controlPointPosition) => {
const line = this._relationship.getLine();
line.setTo(relationPosition.x, relationPosition.y);
line.setDestControlPoint(controlPointPosition);
console.log(JSON.stringify(controlPointPosition));
},
() => {
const actionDispatcher = ActionDispatcher.getInstance();
actionDispatcher.moveControlPoint(this, PivotType.End);
relationship.setOnFocus(true);
},
);
this._pivotLines = [startControlLine, endControlLine];
}
addToWorkspace(workspace: Workspace): void {
this._pivotLines.forEach((pivot) => workspace.append(pivot));
}
removeFromWorkspace(workspace: Workspace) {
this._pivotLines.forEach((pivot) => workspace.removeChild(pivot));
}
getRelationship() {
return this._relationship;
}
redraw() {
this._pivotLines.forEach((pivot) => pivot.redraw());
}
setVisibility(value: boolean) {
this._pivotLines.forEach((pivot) => pivot.setVisibility(value));
}
getControlPointPosition(pivotType: PivotType): PositionType {
return this._pivotLines[pivotType].getPosition();
}
getRelationshipPosition(index: number): PositionType {
return { ...this._relationshipLinePositions[index] };
}
}
export default RelationshipControlPoints;

View File

@ -35,6 +35,7 @@ import RelationshipModel from './model/RelationshipModel';
import Topic from './Topic'; import Topic from './Topic';
import Command from './Command'; import Command from './Command';
import FeatureType from './model/FeatureType'; import FeatureType from './model/FeatureType';
import RelationshipControlPoints from './RelationshipControlPoints';
class StandaloneActionDispatcher extends ActionDispatcher { class StandaloneActionDispatcher extends ActionDispatcher {
private _actionRunner: DesignerActionRunner; private _actionRunner: DesignerActionRunner;
@ -93,8 +94,8 @@ class StandaloneActionDispatcher extends ActionDispatcher {
} }
/** */ /** */
moveControlPoint(ctrlPoint: Point, point: Point) { moveControlPoint(ctrlPoint: RelationshipControlPoints, index: number) {
const command = new MoveControlPointCommand(ctrlPoint, point); const command = new MoveControlPointCommand(ctrlPoint, index);
this.execute(command); this.execute(command);
} }

View File

@ -113,7 +113,7 @@ class Workspace {
} }
private appendInternal(shape: Element2D): void { private appendInternal(shape: Element2D): void {
if ($defined(shape.addToWorkspace)) { if (shape.addToWorkspace) {
shape.addToWorkspace(this); shape.addToWorkspace(this);
} else { } else {
this._workspace.append(shape); this._workspace.append(shape);
@ -156,7 +156,7 @@ class Workspace {
removeChild(shape: Element2D): void { removeChild(shape: Element2D): void {
// Element is a node, not a web2d element? // Element is a node, not a web2d element?
if ($defined(shape.removeFromWorkspace)) { if (shape.removeFromWorkspace) {
shape.removeFromWorkspace(this); shape.removeFromWorkspace(this);
} else { } else {
this._workspace.removeChild(shape); this._workspace.removeChild(shape);

View File

@ -15,28 +15,18 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js';
import { Line } from '@wisemapping/web2d';
import Command from '../Command'; import Command from '../Command';
import ControlPoint from '../ControlPoint'; import RelationshipControlPoints from '../RelationshipControlPoints';
import PositionType from '../PositionType'; import PositionType from '../PositionType';
class MoveControlPointCommand extends Command { class MoveControlPointCommand extends Command {
private _ctrlPointControler: ControlPoint; private _controlPoints: RelationshipControlPoints;
private _line: Line; private _ctrPointPosition: PositionType;
private _controlPoint: Line; private _endPosition: PositionType;
private _oldControlPoint: Line; private _controlPointIndex: number;
private _originalEndPoint: PositionType;
private _wasCustom: boolean;
private _endPoint: any;
private _point: number;
/** /**
* @classdesc This command handles do/undo of changing the control points of a relationship * @classdesc This command handles do/undo of changing the control points of a relationship
@ -44,85 +34,72 @@ class MoveControlPointCommand extends Command {
* influence how the arrow is drawn (not the source or the destination topic nor the arrow * influence how the arrow is drawn (not the source or the destination topic nor the arrow
* direction) * direction)
*/ */
constructor(ctrlPointController: ControlPoint, point: number) { constructor(controlPoints: RelationshipControlPoints, controlPointIndex: number) {
$assert(ctrlPointController, 'line can not be null');
$assert($defined(point), 'point can not be null');
super(); super();
this._ctrlPointControler = ctrlPointController; this._ctrPointPosition = controlPoints.getControlPointPosition(controlPointIndex);
this._line = ctrlPointController._line; this._controlPointIndex = controlPointIndex;
this._controlPoint = { ...this._ctrlPointControler.getControlPoint(point) }; this._controlPoints = controlPoints;
this._oldControlPoint = { ...this._ctrlPointControler.getOriginalCtrlPoint(point) };
this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point); const relLine = controlPoints.getRelationship().getLine();
switch (point) { this._endPosition = controlPointIndex === 0 ? relLine.getFrom() : relLine.getTo();
case 0:
this._wasCustom = this._line.getLine().isSrcControlPointCustom();
this._endPoint = { ...this._line.getLine().getFrom() };
break;
case 1:
this._wasCustom = this._line.getLine().isDestControlPointCustom();
this._endPoint = { ...this._line.getLine().getTo() };
break;
default:
break;
}
this._point = point;
} }
execute() { execute() {
const model = this._line.getModel(); const relationship = this._controlPoints.getRelationship();
switch (this._point) { const model = relationship.getModel();
switch (this._controlPointIndex) {
case 0: case 0:
model.setSrcCtrlPoint({ ...this._controlPoint }); model.setSrcCtrlPoint(this._ctrPointPosition);
this._line.setFrom(this._endPoint.x, this._endPoint.y); relationship.setIsSrcControlPointCustom(true);
this._line.setIsSrcControlPointCustom(true);
this._line.setSrcControlPoint({ ...this._controlPoint }); relationship.setFrom(this._endPosition.x, this._endPosition.y);
relationship.setSrcControlPoint(this._ctrPointPosition);
break; break;
case 1: case 1:
model.setDestCtrlPoint({ ...this._controlPoint }); model.setDestCtrlPoint(this._ctrPointPosition);
this._wasCustom = this._line.getLine().isDestControlPointCustom(); relationship.setIsDestControlPointCustom(true);
this._line.setTo(this._endPoint.x, this._endPoint.y);
this._line.setIsDestControlPointCustom(true); relationship.setTo(this._endPosition.x, this._endPosition.y);
this._line.setDestControlPoint({ ...this._controlPoint }); relationship.setDestControlPoint(this._ctrPointPosition);
break; break;
default: default:
break; throw new Error('Illegal state exception');
} }
if (this._line.isOnFocus()) {
this._line._refreshShape(); if (relationship.isOnFocus()) {
this._ctrlPointControler.setLine(this._line); relationship.refreshShape();
} }
this._line.getLine().updateLine(this._point); // this.relationship.getLine().updateLine(this._point);
} }
undoExecute() { undoExecute() {
const line = this._line; // const line = this._line;
const model = line.getModel(); // const model = line.getModel();
switch (this._point) { // switch (this._controlPointIndex) {
case 0: // case 0:
if ($defined(this._oldControlPoint)) { // if ($defined(this._oldControlPoint)) {
line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y); // line.setFrom(this._oldRelEndpoint.x, this._oldRelEndpoint.y);
model.setSrcCtrlPoint({ ...this._oldControlPoint }); // model.setSrcCtrlPoint({ ...this._oldControlPoint });
line.setSrcControlPoint({ ...this._oldControlPoint }); // line.setSrcControlPoint({ ...this._oldControlPoint });
line.setIsSrcControlPointCustom(this._wasCustom); // line.setIsSrcControlPointCustom(this._isControlPointDefined);
} // }
break; // break;
case 1: // case 1:
if ($defined(this._oldControlPoint)) { // if ($defined(this._oldControlPoint)) {
line.setTo(this._originalEndPoint.x, this._originalEndPoint.y); // line.setTo(this._oldRelEndpoint.x, this._oldRelEndpoint.y);
model.setDestCtrlPoint({ ...this._oldControlPoint }); // model.setDestCtrlPoint({ ...this._oldControlPoint });
line.setDestControlPoint({ ...this._oldControlPoint }); // line.setDestControlPoint({ ...this._oldControlPoint });
line.setIsDestControlPointCustom(this._wasCustom); // line.setIsDestControlPointCustom(this._isControlPointDefined);
} // }
break; // break;
default: // default:
break; // break;
} // }
this._line.getLine().updateLine(this._point); // // this._line.getLine().updateLine(this._point);
if (this._line.isOnFocus()) { // // if (this._line.isOnFocus()) {
this._ctrlPointControler.setLine(line); // // this._ctrlPointControler.setRelationshipLine(line);
line._refreshShape(); // // line._refreshShape();
} // // }
} }
} }

View File

@ -35,10 +35,8 @@ class CurvedLinePeer extends ElementPeer {
setSrcControlPoint(control) { setSrcControlPoint(control) {
this._customControlPoint_1 = true; this._customControlPoint_1 = true;
const change = this._control1.x !== control.x || this._control1.y !== control.y; const change = this._control1.x !== control.x || this._control1.y !== control.y;
if ($defined(control.x)) { if (control) {
this._control1 = control; this._control1 = { ...control };
this._control1.x = Number.parseFloat(this._control1.x, 10);
this._control1.y = Number.parseFloat(this._control1.y, 10);
} }
if (change) { if (change) {
this._updatePath(); this._updatePath();
@ -48,12 +46,12 @@ class CurvedLinePeer extends ElementPeer {
setDestControlPoint(control) { setDestControlPoint(control) {
this._customControlPoint_2 = true; this._customControlPoint_2 = true;
const change = this._control2.x !== control.x || this._control2.y !== control.y; const change = this._control2.x !== control.x || this._control2.y !== control.y;
if ($defined(control.x)) { if (control) {
this._control2 = control; this._control2 = { ...control };
this._control2.x = Number.parseFloat(this._control2.x, 10); }
this._control2.y = Number.parseFloat(this._control2.y, 10); if (change) {
this._updatePath();
} }
if (change) this._updatePath();
} }
isSrcControlPointCustom() { isSrcControlPointCustom() {
@ -73,7 +71,7 @@ class CurvedLinePeer extends ElementPeer {
} }
getControlPoints() { getControlPoints() {
return [this._control1, this._control2]; return [{ ...this._control1 }, { ...this._control2 }];
} }
setFrom(x1, y1) { setFrom(x1, y1) {
@ -155,8 +153,7 @@ class CurvedLinePeer extends ElementPeer {
this._control1.x + this._x1 this._control1.x + this._x1
).toFixed(2)},${this._control1.y + this._y1} ${(this._control2.x + this._x2).toFixed(2)},${( ).toFixed(2)},${this._control1.y + this._y1} ${(this._control2.x + this._x2).toFixed(2)},${(
this._control2.y + this._y2 this._control2.y + this._y2
).toFixed(2)} ${this._x2.toFixed(2)},${this._y2.toFixed(2)}${ ).toFixed(2)} ${this._x2.toFixed(2)},${this._y2.toFixed(2)}${this._lineStyle
this._lineStyle
? ` ${(this._control2.x + this._x2).toFixed(2)},${( ? ` ${(this._control2.x + this._x2).toFixed(2)},${(
this._control2.y + this._control2.y +
this._y2 + this._y2 +