@elyra/canvas 12.36.0 → 12.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas-constants-766c12a9.js +2 -0
- package/dist/{canvas-constants-85883d4c.js.map → canvas-constants-766c12a9.js.map} +1 -1
- package/dist/canvas-constants-f4219d26.js +2 -0
- package/dist/{canvas-constants-d8652829.js.map → canvas-constants-f4219d26.js.map} +1 -1
- package/dist/canvas-controller-62b66fc8.js +2 -0
- package/dist/canvas-controller-62b66fc8.js.map +1 -0
- package/dist/canvas-controller-76f68572.js +2 -0
- package/dist/canvas-controller-76f68572.js.map +1 -0
- package/dist/common-canvas-9be06eb4.js +2 -0
- package/dist/common-canvas-9be06eb4.js.map +1 -0
- package/dist/common-canvas-e201c174.js +2 -0
- package/dist/common-canvas-e201c174.js.map +1 -0
- package/dist/common-canvas.es.js +1 -1
- package/dist/common-canvas.es.js.map +1 -1
- package/dist/common-canvas.js +1 -1
- package/dist/common-canvas.js.map +1 -1
- package/dist/common-properties-7ad71160.js +2 -0
- package/dist/{common-properties-d5775a12.js.map → common-properties-7ad71160.js.map} +1 -1
- package/dist/common-properties-f1c69af7.js +2 -0
- package/dist/{common-properties-a34905c3.js.map → common-properties-f1c69af7.js.map} +1 -1
- package/dist/context-menu-wrapper-624a1e7c.js +2 -0
- package/dist/context-menu-wrapper-624a1e7c.js.map +1 -0
- package/dist/context-menu-wrapper-ab018d6e.js +2 -0
- package/dist/context-menu-wrapper-ab018d6e.js.map +1 -0
- package/dist/{datarecord-metadata-v3-schema-531c7b07.js → datarecord-metadata-v3-schema-1f21696a.js} +2 -2
- package/dist/{datarecord-metadata-v3-schema-531c7b07.js.map → datarecord-metadata-v3-schema-1f21696a.js.map} +1 -1
- package/dist/{datarecord-metadata-v3-schema-28d4d7bb.js → datarecord-metadata-v3-schema-c2ad8862.js} +2 -2
- package/dist/{datarecord-metadata-v3-schema-28d4d7bb.js.map → datarecord-metadata-v3-schema-c2ad8862.js.map} +1 -1
- package/dist/flexible-table-4cf19e2e.js +2 -0
- package/dist/flexible-table-4cf19e2e.js.map +1 -0
- package/dist/flexible-table-8d10f5c9.js +2 -0
- package/dist/flexible-table-8d10f5c9.js.map +1 -0
- package/dist/{icon-909437d7.js → icon-5e06bfe1.js} +2 -2
- package/dist/{icon-909437d7.js.map → icon-5e06bfe1.js.map} +1 -1
- package/dist/{icon-de9c6b33.js → icon-8433d369.js} +2 -2
- package/dist/{icon-de9c6b33.js.map → icon-8433d369.js.map} +1 -1
- package/dist/{index-9960d3bf.js → index-2a61be58.js} +2 -2
- package/dist/{index-9960d3bf.js.map → index-2a61be58.js.map} +1 -1
- package/dist/{index-61e4a113.js → index-9a355ed6.js} +2 -2
- package/dist/{index-61e4a113.js.map → index-9a355ed6.js.map} +1 -1
- package/dist/lib/canvas-controller.es.js +1 -1
- package/dist/lib/canvas-controller.js +1 -1
- package/dist/lib/canvas.es.js +1 -1
- package/dist/lib/canvas.js +1 -1
- package/dist/lib/context-menu.es.js +1 -1
- package/dist/lib/context-menu.js +1 -1
- package/dist/lib/properties/field-picker.es.js +1 -1
- package/dist/lib/properties/field-picker.js +1 -1
- package/dist/lib/properties/flexible-table.es.js +1 -1
- package/dist/lib/properties/flexible-table.js +1 -1
- package/dist/lib/properties.es.js +1 -1
- package/dist/lib/properties.js +1 -1
- package/dist/styles/common-canvas.min.css +1 -1
- package/dist/styles/common-canvas.min.css.map +1 -1
- package/dist/{toolbar-cdb38f4a.js → toolbar-76733735.js} +2 -2
- package/dist/{toolbar-cdb38f4a.js.map → toolbar-76733735.js.map} +1 -1
- package/dist/{toolbar-3b5a592c.js → toolbar-85e1e463.js} +2 -2
- package/dist/{toolbar-3b5a592c.js.map → toolbar-85e1e463.js.map} +1 -1
- package/locales/common-canvas/locales/de.json +1 -0
- package/locales/common-canvas/locales/en.json +1 -1
- package/locales/common-canvas/locales/eo.json +1 -1
- package/locales/common-canvas/locales/es.json +1 -0
- package/locales/common-canvas/locales/fr.json +1 -0
- package/locales/common-canvas/locales/it.json +1 -0
- package/locales/common-canvas/locales/ja.json +1 -0
- package/locales/common-canvas/locales/ko.json +1 -0
- package/locales/common-canvas/locales/pt-br.json +1 -0
- package/locales/common-canvas/locales/sv.json +1 -0
- package/locales/common-canvas/locales/zh-CN.json +1 -0
- package/locales/common-canvas/locales/zh-TW.json +1 -0
- package/package.json +2 -3
- package/src/common-canvas/canvas-controller.js +7 -0
- package/src/common-canvas/cc-contents.jsx +42 -4
- package/src/common-canvas/common-canvas-utils.js +9 -2
- package/src/common-canvas/common-canvas.scss +30 -3
- package/src/common-canvas/constants/canvas-constants.js +0 -6
- package/src/common-canvas/svg-canvas-d3.js +1 -3
- package/src/common-canvas/svg-canvas-d3.scss +0 -26
- package/src/common-canvas/svg-canvas-pipeline.js +6 -0
- package/src/common-canvas/svg-canvas-renderer.js +488 -2815
- package/src/common-canvas/svg-canvas-utils-drag-det-link.js +491 -0
- package/src/common-canvas/svg-canvas-utils-drag-new-link.js +595 -0
- package/src/common-canvas/svg-canvas-utils-drag-objects.js +832 -0
- package/src/common-canvas/svg-canvas-utils-external.js +82 -16
- package/src/common-canvas/svg-canvas-utils-zoom.js +780 -0
- package/src/common-properties/properties-controller.js +5 -0
- package/src/context-menu/common-context-menu.jsx +57 -26
- package/src/context-menu/context-menu.scss +33 -53
- package/src/notification-panel/notification-panel.jsx +21 -21
- package/src/notification-panel/notification-panel.scss +16 -15
- package/src/palette/palette-content-list-item.jsx +23 -7
- package/stats.html +1 -1
- package/dist/canvas-constants-85883d4c.js +0 -2
- package/dist/canvas-constants-d8652829.js +0 -2
- package/dist/canvas-controller-7beb80ec.js +0 -2
- package/dist/canvas-controller-7beb80ec.js.map +0 -1
- package/dist/canvas-controller-b70d0f98.js +0 -2
- package/dist/canvas-controller-b70d0f98.js.map +0 -1
- package/dist/common-canvas-86fb7d21.js +0 -2
- package/dist/common-canvas-86fb7d21.js.map +0 -1
- package/dist/common-canvas-a6bfce5e.js +0 -2
- package/dist/common-canvas-a6bfce5e.js.map +0 -1
- package/dist/common-properties-a34905c3.js +0 -2
- package/dist/common-properties-d5775a12.js +0 -2
- package/dist/context-menu-wrapper-19a1cf72.js +0 -2
- package/dist/context-menu-wrapper-19a1cf72.js.map +0 -1
- package/dist/context-menu-wrapper-c3a98c63.js +0 -2
- package/dist/context-menu-wrapper-c3a98c63.js.map +0 -1
- package/dist/extends-093996c9.js +0 -2
- package/dist/extends-093996c9.js.map +0 -1
- package/dist/extends-1b35a664.js +0 -2
- package/dist/extends-1b35a664.js.map +0 -1
- package/dist/flexible-table-b9c08069.js +0 -2
- package/dist/flexible-table-b9c08069.js.map +0 -1
- package/dist/flexible-table-ddd6132b.js +0 -2
- package/dist/flexible-table-ddd6132b.js.map +0 -1
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2017-2023 Elyra Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/* eslint no-lonely-if: "off" */
|
|
18
|
+
|
|
19
|
+
import * as d3Drag from "d3-drag";
|
|
20
|
+
import * as d3Selection from "d3-selection";
|
|
21
|
+
const d3 = Object.assign({}, d3Drag, d3Selection);
|
|
22
|
+
|
|
23
|
+
import { cloneDeep } from "lodash";
|
|
24
|
+
|
|
25
|
+
import Logger from "../logging/canvas-logger.js";
|
|
26
|
+
import CanvasUtils from "./common-canvas-utils.js";
|
|
27
|
+
import { LINK_SELECTION_DETACHABLE, PORT_OBJECT_IMAGE }
|
|
28
|
+
from "./constants/canvas-constants.js";
|
|
29
|
+
|
|
30
|
+
const INPUT_TYPE = "input_type";
|
|
31
|
+
const OUTPUT_TYPE = "output_type";
|
|
32
|
+
|
|
33
|
+
// This utility files provides a drag handler which manages drag operations on
|
|
34
|
+
// the start and end points of detached links.
|
|
35
|
+
|
|
36
|
+
export default class SVGCanvasUtilsDragDetLink {
|
|
37
|
+
constructor(renderer) {
|
|
38
|
+
this.ren = renderer;
|
|
39
|
+
|
|
40
|
+
this.logger = new Logger("SVGCanvasUtilsDragDetLink");
|
|
41
|
+
|
|
42
|
+
// Object to store variables for dynamically drawing detached links.
|
|
43
|
+
this.draggingLinkData = null;
|
|
44
|
+
|
|
45
|
+
// Create a drag handler that can be used with draggable ends of
|
|
46
|
+
// detached links.
|
|
47
|
+
this.dragDetLinkHandler = d3.drag()
|
|
48
|
+
.on("start", this.dragStartDetLinkHandle.bind(this))
|
|
49
|
+
.on("drag", this.dragMoveDetLinkHandle.bind(this))
|
|
50
|
+
.on("end", this.dragEndDetLinkHandle.bind(this));
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Returns the dragResizeObjectHandler
|
|
55
|
+
getDragDetachedLinkHandler() {
|
|
56
|
+
return this.dragDetLinkHandler;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Returns true if a detached link (start or end) is currently being dragged.
|
|
60
|
+
isDragging() {
|
|
61
|
+
return this.draggingLinkData;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Returns true if the link passed in is currently being dragged.
|
|
65
|
+
isLinkBeingDragged(link) {
|
|
66
|
+
return this.draggingLinkData && this.draggingLinkData.link.id === link.id;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Begins the dragging of a link handle of a detachable link.
|
|
70
|
+
dragStartDetLinkHandle(d3Event, d) {
|
|
71
|
+
this.logger.logStartTimer("dragStartDetLinkHandle");
|
|
72
|
+
|
|
73
|
+
this.ren.closeContextMenuIfOpen();
|
|
74
|
+
|
|
75
|
+
const handleSelection = d3.select(d3Event.sourceEvent.currentTarget);
|
|
76
|
+
const link = this.ren.activePipeline.getLink(d.id);
|
|
77
|
+
const oldLink = cloneDeep(link);
|
|
78
|
+
|
|
79
|
+
const linkGrpSelector = this.ren.getLinkGroupSelectionById(d.id);
|
|
80
|
+
|
|
81
|
+
this.draggingLinkData = {
|
|
82
|
+
lineInfo: d,
|
|
83
|
+
link: link,
|
|
84
|
+
oldLink: oldLink,
|
|
85
|
+
linkGrpSelection: d3.select(linkGrpSelector)
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (handleSelection.attr("class").includes("d3-link-handle-end")) {
|
|
89
|
+
this.draggingLinkData.endBeingDragged = "end";
|
|
90
|
+
|
|
91
|
+
} else if (handleSelection.attr("class").includes("d3-link-handle-start")) {
|
|
92
|
+
this.draggingLinkData.endBeingDragged = "start";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (this.ren.config.enableHighlightUnavailableNodes) {
|
|
96
|
+
if (this.draggingLinkData.endBeingDragged === "end") {
|
|
97
|
+
const links = this.ren.activePipeline.links.filter((lnk) => lnk.id !== link.id);
|
|
98
|
+
this.ren.setUnavailableTargetNodesHighlighting(
|
|
99
|
+
this.ren.activePipeline.getNode(this.draggingLinkData.link.srcNodeId),
|
|
100
|
+
this.draggingLinkData.link.srcNodePortId,
|
|
101
|
+
links
|
|
102
|
+
);
|
|
103
|
+
} else if (this.draggingLinkData.endBeingDragged === "start") {
|
|
104
|
+
const links = this.ren.activePipeline.links.filter((lnk) => lnk.id !== link.id);
|
|
105
|
+
this.ren.setUnavailableSourceNodesHighlighting(
|
|
106
|
+
this.ren.activePipeline.getNode(this.draggingLinkData.oldLink.trgNodeId),
|
|
107
|
+
this.draggingLinkData.link.trgNodePortId,
|
|
108
|
+
links
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.dragLinkHandle(d3Event);
|
|
114
|
+
this.logger.logEndTimer("dragStartDetLinkHandle", true);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Display a link when its handle is being dragged.
|
|
118
|
+
dragMoveDetLinkHandle(d3Event) {
|
|
119
|
+
this.logger.logStartTimer("dragMoveDetLinkHandle");
|
|
120
|
+
this.dragLinkHandle(d3Event);
|
|
121
|
+
this.logger.logEndTimer("dragMoveDetLinkHandle", true);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Completes the dragging of a link handle.
|
|
125
|
+
dragEndDetLinkHandle(d3Event) {
|
|
126
|
+
this.logger.logStartTimer("dragEndLinkHandle");
|
|
127
|
+
this.completeDraggedDetLink(d3Event);
|
|
128
|
+
this.logger.logEndTimer("dragEndLinkHandle", true);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
dragLinkHandle(d3Event) {
|
|
132
|
+
const transPos = this.ren.getTransformedMousePos(d3Event);
|
|
133
|
+
const link = this.draggingLinkData.link;
|
|
134
|
+
|
|
135
|
+
if (this.draggingLinkData.endBeingDragged === "start") {
|
|
136
|
+
link.srcPos = { x_pos: transPos.x, y_pos: transPos.y };
|
|
137
|
+
delete link.srcNodeId;
|
|
138
|
+
delete link.srcNodePortId;
|
|
139
|
+
delete link.srcObj;
|
|
140
|
+
|
|
141
|
+
} else {
|
|
142
|
+
link.trgPos = { x_pos: transPos.x, y_pos: transPos.y };
|
|
143
|
+
delete link.trgNodeId;
|
|
144
|
+
delete link.trgNodePortId;
|
|
145
|
+
delete link.trgNode;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.ren.displayLinks();
|
|
149
|
+
|
|
150
|
+
// Switch on an attribute to indicate a new link is being dragged
|
|
151
|
+
// towards and over a target node.
|
|
152
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
153
|
+
this.setDetachedLinkOverNode(d3Event);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
completeDraggedDetLink(d3Event) {
|
|
158
|
+
const newLink = this.getNewLinkOnDrag(d3Event);
|
|
159
|
+
|
|
160
|
+
// Save a local reference to this.draggingLinkData so we can set it to null before
|
|
161
|
+
// calling the canvas-controller. This means the this.draggingLinkData object will
|
|
162
|
+
// be null when the canvas is refreshed.
|
|
163
|
+
const draggingLinkData = this.draggingLinkData;
|
|
164
|
+
this.draggingLinkData = null;
|
|
165
|
+
|
|
166
|
+
if (newLink) {
|
|
167
|
+
const editSubType = this.getLinkEditSubType(draggingLinkData.oldLink, newLink);
|
|
168
|
+
// If editSubType is set the user did a gesture that requires a change
|
|
169
|
+
// to the object model.
|
|
170
|
+
if (editSubType) {
|
|
171
|
+
this.ren.canvasController.editActionHandler({
|
|
172
|
+
editType: "updateLink",
|
|
173
|
+
editSubType: editSubType,
|
|
174
|
+
editSource: "canvas",
|
|
175
|
+
newLink: newLink,
|
|
176
|
+
pipelineId: this.ren.activePipeline.id });
|
|
177
|
+
// If editSubType is null, the user performed a gesture which should
|
|
178
|
+
// not be executed as an action so draw the link back in its old position.
|
|
179
|
+
} else {
|
|
180
|
+
this.snapBackOldLink(draggingLinkData.oldLink);
|
|
181
|
+
}
|
|
182
|
+
// newLink might be null when we are dragging a link handle with
|
|
183
|
+
// enableLinkSelection not set to detachable. If that's the case the
|
|
184
|
+
// link needs to snap back (redrawn) to its original position.
|
|
185
|
+
} else {
|
|
186
|
+
this.snapBackOldLink(draggingLinkData.oldLink);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Switch 'new link over node' highlighting off
|
|
190
|
+
if (this.ren.config.enableHighlightNodeOnNewLinkDrag) {
|
|
191
|
+
this.ren.setLinkOverNodeCancel();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
this.ren.unsetUnavailableNodesHighlighting();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Returns the edit sub-type for the link action being performed to further
|
|
198
|
+
// explain the updateLink action.
|
|
199
|
+
getLinkEditSubType(oldLink, newLink) {
|
|
200
|
+
if (oldLink.srcNodeId && !newLink.srcNodeId) {
|
|
201
|
+
return "detachFromSrcNode";
|
|
202
|
+
|
|
203
|
+
} else if (oldLink.trgNodeId && !newLink.trgNodeId) {
|
|
204
|
+
return "detachFromTrgNode";
|
|
205
|
+
|
|
206
|
+
} else if (!oldLink.srcNodeId && newLink.srcNodeId) {
|
|
207
|
+
return "attachToSrcNode";
|
|
208
|
+
|
|
209
|
+
} else if (!oldLink.trgNodeId && newLink.trgNodeId) {
|
|
210
|
+
return "attachToTrgNode";
|
|
211
|
+
|
|
212
|
+
} else if (!oldLink.srcNodeId && !newLink.srcNodeId &&
|
|
213
|
+
(oldLink.srcPos.x_pos !== newLink.srcPos.x_pos ||
|
|
214
|
+
oldLink.srcPos.y_pos !== newLink.srcPos.y_pos)) {
|
|
215
|
+
return "moveSrcPosition";
|
|
216
|
+
|
|
217
|
+
} else if (!oldLink.trgNodeId && !newLink.trgNodeId &&
|
|
218
|
+
(oldLink.trgPos.x_pos !== newLink.trgPos.x_pos ||
|
|
219
|
+
oldLink.trgPos.y_pos !== newLink.trgPos.y_pos)) {
|
|
220
|
+
return "moveTrgPosition";
|
|
221
|
+
|
|
222
|
+
} else if (oldLink.srcNodeId && newLink.srcNodeId &&
|
|
223
|
+
oldLink.srcNodeId !== newLink.srcNodeId) {
|
|
224
|
+
return "switchSrcNode";
|
|
225
|
+
|
|
226
|
+
} else if (oldLink.trgNodeId && newLink.trgNodeId &&
|
|
227
|
+
oldLink.trgNodeId !== newLink.trgNodeId) {
|
|
228
|
+
return "switchTrgNode";
|
|
229
|
+
|
|
230
|
+
} else if (oldLink.srcNodeId && newLink.srcNodeId &&
|
|
231
|
+
oldLink.srcNodeId === newLink.srcNodeId &&
|
|
232
|
+
oldLink.srcNodePortId !== newLink.srcNodePortId) {
|
|
233
|
+
return "switchSrcNodePort";
|
|
234
|
+
|
|
235
|
+
} else if (oldLink.trgNodeId && newLink.trgNodeId &&
|
|
236
|
+
oldLink.trgNodeId === newLink.trgNodeId &&
|
|
237
|
+
oldLink.trgNodePortId !== newLink.trgNodePortId) {
|
|
238
|
+
return "switchTrgNodePort";
|
|
239
|
+
}
|
|
240
|
+
// We arrive here, in two ways:
|
|
241
|
+
// 1. if the user dragged a link handle from a node/port and dropped it
|
|
242
|
+
// back on the same node/port.
|
|
243
|
+
// 2. If the user clicked on the unattached end of a detached link but did
|
|
244
|
+
// not move it anywhere
|
|
245
|
+
// In these cases, the updateLink action should NOT be performed and
|
|
246
|
+
// consequently NO command should be added to the command stack.
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Resets and redraws the link being dragged back to its original position.
|
|
251
|
+
// This is necessary when the user performs a link drag gesture which should
|
|
252
|
+
// NOT be executed as an action -- therefore the link need to be drawn back
|
|
253
|
+
// in its original position.
|
|
254
|
+
snapBackOldLink(oldLink) {
|
|
255
|
+
this.ren.activePipeline.replaceLink(oldLink);
|
|
256
|
+
this.ren.displayLinks();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Switches on or off node port highlighting depending on the node
|
|
260
|
+
// passed in and keeps track of the currently highlighted node. This is
|
|
261
|
+
// called as a new link is being drawn towards a target node to highlight
|
|
262
|
+
// the target node.
|
|
263
|
+
setDetachedLinkOverNode(d3Event) {
|
|
264
|
+
const nodeNearMouse = this.ren.getNodeNearMousePos(d3Event, this.ren.canvasLayout.nodeProximity);
|
|
265
|
+
const highlight = nodeNearMouse && this.isDetLinkConnectionAllowedToNearbyNode(d3Event);
|
|
266
|
+
this.ren.setHighlightingOverNode(highlight, nodeNearMouse);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Returns true if a detached link being dragged can be attached to a node.
|
|
270
|
+
isDetLinkConnectionAllowedToNearbyNode(d3Event) {
|
|
271
|
+
if (this.draggingLinkData) {
|
|
272
|
+
const newLink = this.getNewLinkOnDrag(d3Event, this.ren.canvasLayout.nodeProximity);
|
|
273
|
+
if (newLink) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Returns a new link if one can be created given the current data in the
|
|
281
|
+
// this.draggingLinkData object. Returns null if a link cannot be created.
|
|
282
|
+
getNewLinkOnDrag(d3Event, nodeProximity) {
|
|
283
|
+
const oldLink = this.draggingLinkData.oldLink;
|
|
284
|
+
const newLink = cloneDeep(oldLink);
|
|
285
|
+
|
|
286
|
+
if (this.draggingLinkData.endBeingDragged === "start") {
|
|
287
|
+
delete newLink.srcObj;
|
|
288
|
+
delete newLink.srcNodeId;
|
|
289
|
+
delete newLink.srcNodePortId;
|
|
290
|
+
delete newLink.srcPos;
|
|
291
|
+
|
|
292
|
+
const srcNode = nodeProximity
|
|
293
|
+
? this.ren.getNodeNearMousePos(d3Event, nodeProximity)
|
|
294
|
+
: this.ren.getNodeAtMousePos(d3Event);
|
|
295
|
+
|
|
296
|
+
if (srcNode) {
|
|
297
|
+
newLink.srcNodeId = srcNode.id;
|
|
298
|
+
newLink.srcObj = this.ren.activePipeline.getNode(srcNode.id);
|
|
299
|
+
newLink.srcNodePortId = nodeProximity
|
|
300
|
+
? this.getNodePortIdNearMousePos(d3Event, OUTPUT_TYPE, srcNode)
|
|
301
|
+
: this.ren.getOutputNodePortId(d3Event, srcNode);
|
|
302
|
+
} else {
|
|
303
|
+
newLink.srcPos = this.draggingLinkData.link.srcPos;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
} else {
|
|
307
|
+
delete newLink.trgNode;
|
|
308
|
+
delete newLink.trgNodeId;
|
|
309
|
+
delete newLink.trgNodePortId;
|
|
310
|
+
delete newLink.trgPos;
|
|
311
|
+
|
|
312
|
+
const trgNode = nodeProximity
|
|
313
|
+
? this.ren.getNodeNearMousePos(d3Event, nodeProximity)
|
|
314
|
+
: this.ren.getNodeAtMousePos(d3Event);
|
|
315
|
+
|
|
316
|
+
if (trgNode) {
|
|
317
|
+
newLink.trgNodeId = trgNode.id;
|
|
318
|
+
newLink.trgNode = this.ren.activePipeline.getNode(trgNode.id);
|
|
319
|
+
newLink.trgNodePortId = nodeProximity
|
|
320
|
+
? this.getNodePortIdNearMousePos(d3Event, INPUT_TYPE, trgNode)
|
|
321
|
+
: this.ren.getInputNodePortId(d3Event, trgNode);
|
|
322
|
+
} else {
|
|
323
|
+
newLink.trgPos = this.draggingLinkData.link.trgPos;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// If links are not detachable, we cannot create a link if srcPos
|
|
328
|
+
// or trgPos are set because that would create a detached link unconnected
|
|
329
|
+
// to either a source node or a target node or both.
|
|
330
|
+
if (this.ren.config.enableLinkSelection !== LINK_SELECTION_DETACHABLE &&
|
|
331
|
+
(newLink.srcPos || newLink.trgPos)) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (this.canExecuteUpdateLinkCommand(newLink, oldLink)) {
|
|
336
|
+
return newLink;
|
|
337
|
+
}
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Returns the ID of the port, of the type specified, near to the
|
|
342
|
+
// mouse cursor position.
|
|
343
|
+
getNodePortIdNearMousePos(d3Event, portType, node) {
|
|
344
|
+
const pos = this.ren.getTransformedMousePos(d3Event);
|
|
345
|
+
let portId = null;
|
|
346
|
+
let defaultPortId = null;
|
|
347
|
+
|
|
348
|
+
if (node) {
|
|
349
|
+
if (portType === OUTPUT_TYPE) {
|
|
350
|
+
const portObjs = this.ren.getAllNodeGroupsSelection()
|
|
351
|
+
.selectChildren("." + this.ren.getNodeOutputPortClassName())
|
|
352
|
+
.selectChildren(".d3-node-port-output-main");
|
|
353
|
+
|
|
354
|
+
portId = this.searchForPortNearMouse(
|
|
355
|
+
node, pos, portObjs,
|
|
356
|
+
node.layout.outputPortObject,
|
|
357
|
+
node.width);
|
|
358
|
+
defaultPortId = CanvasUtils.getDefaultOutputPortId(node);
|
|
359
|
+
|
|
360
|
+
} else {
|
|
361
|
+
const portObjs = this.ren.getAllNodeGroupsSelection()
|
|
362
|
+
.selectChildren("." + this.ren.getNodeInputPortClassName())
|
|
363
|
+
.selectChildren(".d3-node-port-input-main");
|
|
364
|
+
|
|
365
|
+
portId = this.searchForPortNearMouse(
|
|
366
|
+
node, pos, portObjs,
|
|
367
|
+
node.layout.inputPortObject,
|
|
368
|
+
0);
|
|
369
|
+
defaultPortId = CanvasUtils.getDefaultInputPortId(node);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (!portId) {
|
|
374
|
+
portId = defaultPortId;
|
|
375
|
+
}
|
|
376
|
+
return portId;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Returns a port ID for the port identified by the position (pos) on the
|
|
380
|
+
// node (node) further specified by the other parameters.
|
|
381
|
+
searchForPortNearMouse(node, pos, portObjs, portObjectType, nodeWidthOffset) {
|
|
382
|
+
let portId = null;
|
|
383
|
+
portObjs
|
|
384
|
+
.each((p, i, portGrps) => {
|
|
385
|
+
const portSel = d3.select(portGrps[i]);
|
|
386
|
+
if (portObjectType === PORT_OBJECT_IMAGE) {
|
|
387
|
+
const xx = node.x_pos + Number(portSel.attr("x"));
|
|
388
|
+
const yy = node.y_pos + Number(portSel.attr("y"));
|
|
389
|
+
const wd = Number(portSel.attr("width"));
|
|
390
|
+
const ht = Number(portSel.attr("height"));
|
|
391
|
+
if (pos.x >= xx &&
|
|
392
|
+
pos.x <= xx + nodeWidthOffset + wd &&
|
|
393
|
+
pos.y >= yy &&
|
|
394
|
+
pos.y <= yy + ht) {
|
|
395
|
+
portId = portGrps[i].getAttribute("data-port-id");
|
|
396
|
+
}
|
|
397
|
+
} else { // Port must be a circle
|
|
398
|
+
const cx = node.x_pos + Number(portSel.attr("cx"));
|
|
399
|
+
const cy = node.y_pos + Number(portSel.attr("cy"));
|
|
400
|
+
if (pos.x >= cx - node.layout.portRadius && // Target port sticks out by its radius so need to allow for it.
|
|
401
|
+
pos.x <= cx + node.layout.portRadius &&
|
|
402
|
+
pos.y >= cy - node.layout.portRadius &&
|
|
403
|
+
pos.y <= cy + node.layout.portRadius) {
|
|
404
|
+
portId = portGrps[i].getAttribute("data-port-id");
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
return portId;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Returns true if the update command for a dragged link can be executed.
|
|
413
|
+
// It might be prevented from executing if either the course
|
|
414
|
+
canExecuteUpdateLinkCommand(newLink, oldLink) {
|
|
415
|
+
const srcNode = this.ren.activePipeline.getNode(newLink.srcNodeId);
|
|
416
|
+
const trgNode = this.ren.activePipeline.getNode(newLink.trgNodeId);
|
|
417
|
+
const linkSrcChanged = this.hasLinkSrcChanged(newLink, oldLink);
|
|
418
|
+
const linkTrgChanged = this.hasLinkTrgChanged(newLink, oldLink);
|
|
419
|
+
const links = this.ren.activePipeline.links;
|
|
420
|
+
let executeCommand = true;
|
|
421
|
+
|
|
422
|
+
if (linkSrcChanged && srcNode &&
|
|
423
|
+
!CanvasUtils.isSrcConnectionAllowedWithDetachedLinks(newLink.srcNodePortId, srcNode, links)) {
|
|
424
|
+
executeCommand = false;
|
|
425
|
+
}
|
|
426
|
+
if (linkTrgChanged && trgNode &&
|
|
427
|
+
!CanvasUtils.isTrgConnectionAllowedWithDetachedLinks(newLink.trgNodePortId, trgNode, links)) {
|
|
428
|
+
executeCommand = false;
|
|
429
|
+
}
|
|
430
|
+
if (srcNode && trgNode &&
|
|
431
|
+
!CanvasUtils.isConnectionAllowedWithDetachedLinks(newLink.srcNodePortId, newLink.trgNodePortId, srcNode, trgNode, links)) {
|
|
432
|
+
executeCommand = false;
|
|
433
|
+
}
|
|
434
|
+
return executeCommand;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Returns true if the source information has changed between
|
|
438
|
+
// the two links.
|
|
439
|
+
hasLinkSrcChanged(newLink, oldLink) {
|
|
440
|
+
let linkUpdated = false;
|
|
441
|
+
|
|
442
|
+
if (newLink.srcNodeId) {
|
|
443
|
+
if (newLink.srcNodeId !== oldLink.srcNodeId) {
|
|
444
|
+
linkUpdated = true;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (newLink.srcNodePortId !== oldLink.srcNodePortId) {
|
|
448
|
+
linkUpdated = true;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
} else {
|
|
452
|
+
if (oldLink.srcPos) {
|
|
453
|
+
if (newLink.srcPos.x_pos !== oldLink.srcPos.x_pos ||
|
|
454
|
+
newLink.srcPos.y_pos !== oldLink.srcPos.y_pos) {
|
|
455
|
+
linkUpdated = true;
|
|
456
|
+
}
|
|
457
|
+
} else {
|
|
458
|
+
linkUpdated = true;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return linkUpdated;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Returns true if the target information has changed between
|
|
465
|
+
// the two links.
|
|
466
|
+
hasLinkTrgChanged(newLink, oldLink) {
|
|
467
|
+
let linkUpdated = false;
|
|
468
|
+
|
|
469
|
+
if (newLink.trgNodeId) {
|
|
470
|
+
if (newLink.trgNodeId !== oldLink.trgNodeId) {
|
|
471
|
+
linkUpdated = true;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (newLink.trgNodePortId !== oldLink.trgNodePortId) {
|
|
475
|
+
linkUpdated = true;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
} else {
|
|
479
|
+
if (oldLink.trgPos) {
|
|
480
|
+
if (newLink.trgPos.x_pos !== oldLink.trgPos.x_pos ||
|
|
481
|
+
newLink.trgPos.y_pos !== oldLink.trgPos.y_pos) {
|
|
482
|
+
linkUpdated = true;
|
|
483
|
+
}
|
|
484
|
+
} else {
|
|
485
|
+
linkUpdated = true;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return linkUpdated;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
}
|