2021-07-16 16:41:58 +02:00
|
|
|
/*
|
2021-12-25 23:39:34 +01:00
|
|
|
* Copyright [2021] [wisemapping]
|
2021-07-16 16:41:58 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2021-12-19 17:31:29 +01:00
|
|
|
import { CurvedLine, Arrow, Point } from '@wisemapping/web2d';
|
2021-12-03 19:58:25 +01:00
|
|
|
import { $assert } from '@wisemapping/core-js';
|
|
|
|
import Relationship from './Relationship';
|
2021-12-02 01:41:56 +01:00
|
|
|
import Shape from './util/Shape';
|
2021-07-16 16:41:58 +02:00
|
|
|
|
2021-12-05 00:39:20 +01:00
|
|
|
class RelationshipPivot {
|
|
|
|
constructor(workspace, designer) {
|
2021-10-05 02:05:34 +02:00
|
|
|
$assert(workspace, 'workspace can not be null');
|
|
|
|
$assert(designer, 'designer can not be null');
|
|
|
|
this._workspace = workspace;
|
|
|
|
this._designer = designer;
|
|
|
|
|
|
|
|
// FIXME: the aim of the migration is remove .bind mootools method, please remove these!
|
|
|
|
this._mouseMoveEvent = this._mouseMove.bind(this);
|
|
|
|
this._onClickEvent = this._cleanOnMouseClick.bind(this);
|
|
|
|
this._onTopicClick = this._connectOnFocus.bind(this);
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
start(sourceTopic, targetPos) {
|
|
|
|
$assert(sourceTopic, 'sourceTopic can not be null');
|
|
|
|
$assert(targetPos, 'targetPos can not be null');
|
|
|
|
|
|
|
|
this.dispose();
|
|
|
|
this._sourceTopic = sourceTopic;
|
|
|
|
if (sourceTopic != null) {
|
|
|
|
this._workspace.enableWorkspaceEvents(false);
|
|
|
|
|
|
|
|
const sourcePos = sourceTopic.getPosition();
|
|
|
|
const strokeColor = Relationship.getStrokeColor();
|
|
|
|
|
2021-12-19 17:31:29 +01:00
|
|
|
this._pivot = new CurvedLine();
|
|
|
|
this._pivot.setStyle(CurvedLine.SIMPLE_LINE);
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
const fromPos = this._calculateFromPosition(sourcePos);
|
|
|
|
this._pivot.setFrom(fromPos.x, fromPos.y);
|
|
|
|
|
|
|
|
this._pivot.setTo(targetPos.x, targetPos.y);
|
|
|
|
this._pivot.setStroke(2, 'solid', strokeColor);
|
|
|
|
this._pivot.setDashed(4, 2);
|
|
|
|
|
2021-12-19 17:31:29 +01:00
|
|
|
this._startArrow = new Arrow();
|
2021-10-05 02:05:34 +02:00
|
|
|
this._startArrow.setStrokeColor(strokeColor);
|
|
|
|
this._startArrow.setStrokeWidth(2);
|
|
|
|
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
|
|
|
|
|
|
|
|
this._workspace.append(this._pivot);
|
|
|
|
this._workspace.append(this._startArrow);
|
|
|
|
|
|
|
|
this._workspace.addEvent('mousemove', this._mouseMoveEvent);
|
|
|
|
this._workspace.addEvent('click', this._onClickEvent);
|
|
|
|
|
|
|
|
// Register focus events on all topics ...
|
|
|
|
const model = this._designer.getModel();
|
|
|
|
const topics = model.getTopics();
|
2021-12-05 17:14:15 +01:00
|
|
|
topics.forEach((topic) => {
|
2021-10-05 02:05:34 +02:00
|
|
|
topic.addEvent('ontfocus', this._onTopicClick);
|
|
|
|
});
|
|
|
|
}
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
dispose() {
|
|
|
|
const workspace = this._workspace;
|
|
|
|
|
|
|
|
if (this._isActive()) {
|
|
|
|
workspace.removeEvent('mousemove', this._mouseMoveEvent);
|
|
|
|
workspace.removeEvent('click', this._onClickEvent);
|
|
|
|
|
|
|
|
const model = this._designer.getModel();
|
|
|
|
const topics = model.getTopics();
|
2021-12-05 17:14:15 +01:00
|
|
|
|
|
|
|
topics.forEach(((topic) => {
|
|
|
|
topic.removeEvent('ontfocus', this._onTopicClick);
|
2021-12-14 16:08:54 +01:00
|
|
|
}));
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
workspace.removeChild(this._pivot);
|
|
|
|
workspace.removeChild(this._startArrow);
|
|
|
|
workspace.enableWorkspaceEvents(true);
|
|
|
|
|
|
|
|
this._sourceTopic = null;
|
|
|
|
this._pivot = null;
|
|
|
|
this._startArrow = null;
|
|
|
|
}
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_mouseMove(event) {
|
|
|
|
const screen = this._workspace.getScreenManager();
|
|
|
|
const pos = screen.getWorkspaceMousePosition(event);
|
|
|
|
|
|
|
|
// Leave the arrow a couple of pixels away from the cursor.
|
|
|
|
const sourcePosition = this._sourceTopic.getPosition();
|
|
|
|
const gapDistance = Math.sign(pos.x - sourcePosition.x) * 5;
|
|
|
|
|
|
|
|
const sPos = this._calculateFromPosition(pos);
|
|
|
|
this._pivot.setFrom(sPos.x, sPos.y);
|
2021-07-16 16:41:58 +02:00
|
|
|
|
2021-10-05 02:05:34 +02:00
|
|
|
// Update target position ...
|
|
|
|
this._pivot.setTo(pos.x - gapDistance, pos.y);
|
2021-07-16 16:41:58 +02:00
|
|
|
|
2021-10-05 02:05:34 +02:00
|
|
|
const controlPoints = this._pivot.getControlPoints();
|
|
|
|
this._startArrow.setFrom(pos.x - gapDistance, pos.y);
|
|
|
|
this._startArrow.setControlPoint(controlPoints[1]);
|
2021-07-16 16:41:58 +02:00
|
|
|
|
2021-10-05 02:05:34 +02:00
|
|
|
event.stopPropagation();
|
|
|
|
return false;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_cleanOnMouseClick(event) {
|
|
|
|
// The user clicks on a desktop on in other element that is not a node.
|
|
|
|
this.dispose();
|
|
|
|
event.stopPropagation();
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_calculateFromPosition(toPosition) {
|
|
|
|
// Calculate origin position ...
|
|
|
|
let sourcePosition = this._sourceTopic.getPosition();
|
2022-01-02 23:16:18 +01:00
|
|
|
if (this._sourceTopic.getType() === 'CentralTopic') {
|
2021-10-05 02:05:34 +02:00
|
|
|
sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
|
2021-07-16 16:41:58 +02:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
|
|
|
|
2021-12-19 17:31:29 +01:00
|
|
|
const spoint = new Point();
|
2021-12-02 01:41:56 +01:00
|
|
|
spoint.x = parseInt(controlPoint[0].x, 10) + parseInt(sourcePosition.x, 10);
|
|
|
|
spoint.y = parseInt(controlPoint[0].y, 10) + parseInt(sourcePosition.y, 10);
|
2021-10-05 02:05:34 +02:00
|
|
|
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_connectOnFocus(event, targetTopic) {
|
|
|
|
const sourceTopic = this._sourceTopic;
|
|
|
|
const mindmap = this._designer.getMindmap();
|
|
|
|
|
|
|
|
// Avoid circular connections ...
|
2021-12-02 01:41:56 +01:00
|
|
|
if (targetTopic.getId() !== sourceTopic.getId()) {
|
2021-10-05 02:05:34 +02:00
|
|
|
const relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
|
|
|
|
this._designer._actionDispatcher.addRelationship(relModel);
|
|
|
|
}
|
|
|
|
this.dispose();
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_isActive() {
|
|
|
|
return this._pivot != null;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
|
|
|
}
|
2021-07-16 16:41:58 +02:00
|
|
|
|
|
|
|
export default RelationshipPivot;
|