pict-section-flow 0.0.10 → 0.0.13
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/.claude/launch.json +1 -1
- package/README.md +176 -0
- package/docs/.nojekyll +0 -0
- package/docs/Architecture.md +303 -0
- package/docs/Custom-Styling.md +275 -0
- package/docs/Data_Model.md +158 -0
- package/docs/Event_System.md +156 -0
- package/docs/Getting_Started.md +237 -0
- package/docs/Implementation_Reference.md +528 -0
- package/docs/Layout_Persistence.md +117 -0
- package/docs/README.md +115 -52
- package/docs/_cover.md +11 -0
- package/docs/_sidebar.md +52 -0
- package/docs/_topbar.md +8 -0
- package/docs/api/PictFlowCard.md +216 -0
- package/docs/api/PictFlowCardPropertiesPanel.md +235 -0
- package/docs/api/addConnection.md +101 -0
- package/docs/api/addNode.md +137 -0
- package/docs/api/autoLayout.md +77 -0
- package/docs/api/getFlowData.md +112 -0
- package/docs/api/marshalToView.md +95 -0
- package/docs/api/openPanel.md +128 -0
- package/docs/api/registerHandler.md +174 -0
- package/docs/api/registerNodeType.md +142 -0
- package/docs/api/removeConnection.md +57 -0
- package/docs/api/removeNode.md +80 -0
- package/docs/api/saveLayout.md +152 -0
- package/docs/api/screenToSVGCoords.md +68 -0
- package/docs/api/selectNode.md +116 -0
- package/docs/api/setTheme.md +168 -0
- package/docs/api/setZoom.md +97 -0
- package/docs/api/toggleFullscreen.md +68 -0
- package/docs/card-help/EACH.md +19 -0
- package/docs/card-help/FREAD.md +24 -0
- package/docs/card-help/FWRITE.md +24 -0
- package/docs/card-help/GET.md +22 -0
- package/docs/card-help/ITE.md +23 -0
- package/docs/card-help/LOG.md +23 -0
- package/docs/card-help/NOTE.md +17 -0
- package/docs/card-help/PREV.md +18 -0
- package/docs/card-help/SET.md +27 -0
- package/docs/card-help/SPKL.md +22 -0
- package/docs/card-help/STAT.md +23 -0
- package/docs/card-help/SW.md +25 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +169 -0
- package/docs/retold-keyword-index.json +13942 -0
- package/example_applications/simple_cards/package.json +1 -0
- package/example_applications/simple_cards/source/card-help-content.js +16 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Each.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +2 -0
- package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +2 -0
- package/package.json +11 -7
- package/scripts/generate-card-help.js +214 -0
- package/source/Pict-Section-Flow.js +4 -0
- package/source/PictFlowCard.js +3 -1
- package/source/providers/PictProvider-Flow-CSS.js +245 -152
- package/source/providers/PictProvider-Flow-ConnectorShapes.js +24 -0
- package/source/providers/PictProvider-Flow-Geometry.js +195 -38
- package/source/providers/PictProvider-Flow-PanelChrome.js +14 -12
- package/source/services/PictService-Flow-ConnectionHandleManager.js +263 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +134 -183
- package/source/services/PictService-Flow-DataManager.js +338 -0
- package/source/services/PictService-Flow-InteractionManager.js +165 -7
- package/source/services/PictService-Flow-PathGenerator.js +282 -0
- package/source/services/PictService-Flow-PortRenderer.js +269 -0
- package/source/services/PictService-Flow-RenderManager.js +281 -0
- package/source/services/PictService-Flow-Tether.js +6 -42
- package/source/views/PictView-Flow-Node.js +2 -220
- package/source/views/PictView-Flow-PropertiesPanel.js +89 -44
- package/source/views/PictView-Flow.js +130 -882
- package/test/ConnectionHandleManager_tests.js +717 -0
- package/test/ConnectionRenderer_tests.js +591 -0
- package/test/DataManager_tests.js +859 -0
- package/test/Geometry_tests.js +767 -0
- package/test/PathGenerator_tests.js +978 -0
- package/test/PortRenderer_tests.js +367 -0
- package/test/RenderManager_tests.js +756 -0
|
@@ -60,9 +60,15 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
60
60
|
}
|
|
61
61
|
else
|
|
62
62
|
{
|
|
63
|
-
let
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
let tmpHandles = this._getBezierHandles(tmpData);
|
|
64
|
+
if (tmpHandles.length > 0)
|
|
65
|
+
{
|
|
66
|
+
tmpPath = this._generateMultiHandleBezierPath(tmpSourcePos, tmpTargetPos, tmpHandles);
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
{
|
|
70
|
+
tmpPath = this._generateDirectionalPath(tmpSourcePos, tmpTargetPos);
|
|
71
|
+
}
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
// Apply theme noise post-processing to the path
|
|
@@ -168,75 +174,7 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
168
174
|
*/
|
|
169
175
|
_computeDirectionalGeometry(pStart, pEnd)
|
|
170
176
|
{
|
|
171
|
-
|
|
172
|
-
let tmpEndDir = this._FlowView._GeometryProvider.sideDirection(pEnd.side || 'left');
|
|
173
|
-
|
|
174
|
-
let tmpStraightLen = 20;
|
|
175
|
-
|
|
176
|
-
let tmpDepartX = pStart.x + tmpStartDir.dx * tmpStraightLen;
|
|
177
|
-
let tmpDepartY = pStart.y + tmpStartDir.dy * tmpStraightLen;
|
|
178
|
-
|
|
179
|
-
let tmpApproachX = pEnd.x + tmpEndDir.dx * tmpStraightLen;
|
|
180
|
-
let tmpApproachY = pEnd.y + tmpEndDir.dy * tmpStraightLen;
|
|
181
|
-
|
|
182
|
-
let tmpDX = Math.abs(tmpApproachX - tmpDepartX);
|
|
183
|
-
let tmpDY = Math.abs(tmpApproachY - tmpDepartY);
|
|
184
|
-
let tmpDist = Math.sqrt(tmpDX * tmpDX + tmpDY * tmpDY);
|
|
185
|
-
|
|
186
|
-
let tmpBaseOffset = Math.max(Math.min(tmpDist * 0.4, 180), 30);
|
|
187
|
-
|
|
188
|
-
let tmpSameAxis = (tmpStartDir.dx !== 0 && tmpEndDir.dx !== 0) ||
|
|
189
|
-
(tmpStartDir.dy !== 0 && tmpEndDir.dy !== 0);
|
|
190
|
-
|
|
191
|
-
let tmpFacingEachOther = false;
|
|
192
|
-
if (tmpSameAxis)
|
|
193
|
-
{
|
|
194
|
-
if (tmpStartDir.dx === 1 && tmpEndDir.dx === -1 && pEnd.x >= pStart.x)
|
|
195
|
-
{
|
|
196
|
-
tmpFacingEachOther = true;
|
|
197
|
-
}
|
|
198
|
-
else if (tmpStartDir.dx === -1 && tmpEndDir.dx === 1 && pEnd.x <= pStart.x)
|
|
199
|
-
{
|
|
200
|
-
tmpFacingEachOther = true;
|
|
201
|
-
}
|
|
202
|
-
else if (tmpStartDir.dy === 1 && tmpEndDir.dy === -1 && pEnd.y >= pStart.y)
|
|
203
|
-
{
|
|
204
|
-
tmpFacingEachOther = true;
|
|
205
|
-
}
|
|
206
|
-
else if (tmpStartDir.dy === -1 && tmpEndDir.dy === 1 && pEnd.y <= pStart.y)
|
|
207
|
-
{
|
|
208
|
-
tmpFacingEachOther = true;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
let tmpCurveOffset;
|
|
213
|
-
|
|
214
|
-
if (tmpFacingEachOther)
|
|
215
|
-
{
|
|
216
|
-
let tmpInlineDist = (tmpStartDir.dx !== 0) ? tmpDX : tmpDY;
|
|
217
|
-
tmpCurveOffset = Math.max(tmpInlineDist * 0.35, 30);
|
|
218
|
-
}
|
|
219
|
-
else if (tmpSameAxis)
|
|
220
|
-
{
|
|
221
|
-
tmpCurveOffset = Math.max(tmpBaseOffset, 60);
|
|
222
|
-
}
|
|
223
|
-
else
|
|
224
|
-
{
|
|
225
|
-
tmpCurveOffset = Math.max(tmpBaseOffset * 0.8, 40);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
let tmpCP1X = tmpDepartX + tmpStartDir.dx * tmpCurveOffset;
|
|
229
|
-
let tmpCP1Y = tmpDepartY + tmpStartDir.dy * tmpCurveOffset;
|
|
230
|
-
let tmpCP2X = tmpApproachX + tmpEndDir.dx * tmpCurveOffset;
|
|
231
|
-
let tmpCP2Y = tmpApproachY + tmpEndDir.dy * tmpCurveOffset;
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
departX: tmpDepartX, departY: tmpDepartY,
|
|
235
|
-
approachX: tmpApproachX, approachY: tmpApproachY,
|
|
236
|
-
cp1X: tmpCP1X, cp1Y: tmpCP1Y,
|
|
237
|
-
cp2X: tmpCP2X, cp2Y: tmpCP2Y,
|
|
238
|
-
startDir: tmpStartDir, endDir: tmpEndDir
|
|
239
|
-
};
|
|
177
|
+
return this._FlowView._PathGenerator.computeDirectionalGeometry(pStart, pEnd);
|
|
240
178
|
}
|
|
241
179
|
|
|
242
180
|
/**
|
|
@@ -269,67 +207,114 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
269
207
|
}
|
|
270
208
|
|
|
271
209
|
/**
|
|
272
|
-
*
|
|
210
|
+
* Get the bezier handles array from connection data, with backward
|
|
211
|
+
* compatibility for the legacy BezierHandleX/Y single-handle format.
|
|
273
212
|
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
|
|
213
|
+
* @param {Object} pData - Connection.Data
|
|
214
|
+
* @returns {Array<{x: number, y: number}>} Ordered handle waypoints (may be empty)
|
|
215
|
+
*/
|
|
216
|
+
_getBezierHandles(pData)
|
|
217
|
+
{
|
|
218
|
+
if (!pData || !pData.HandleCustomized)
|
|
219
|
+
{
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// New multi-handle format
|
|
224
|
+
if (Array.isArray(pData.BezierHandles) && pData.BezierHandles.length > 0)
|
|
225
|
+
{
|
|
226
|
+
return pData.BezierHandles;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Legacy single-handle format
|
|
230
|
+
if (pData.BezierHandleX != null && pData.BezierHandleY != null)
|
|
231
|
+
{
|
|
232
|
+
return [{ x: pData.BezierHandleX, y: pData.BezierHandleY }];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Generate a multi-handle bezier path between two ports.
|
|
240
|
+
* Delegates to PathGenerator.buildMultiBezierPathString for the
|
|
241
|
+
* actual SVG path assembly with Catmull-Rom tangent continuity.
|
|
277
242
|
*
|
|
278
243
|
* @param {{x: number, y: number, side: string}} pStart
|
|
279
244
|
* @param {{x: number, y: number, side: string}} pEnd
|
|
280
|
-
* @param {number
|
|
281
|
-
* @param {number|null} pHandleY
|
|
245
|
+
* @param {Array<{x: number, y: number}>} pHandles - Ordered waypoints
|
|
282
246
|
* @returns {string} SVG path d attribute
|
|
283
247
|
*/
|
|
284
|
-
|
|
248
|
+
_generateMultiHandleBezierPath(pStart, pEnd, pHandles)
|
|
285
249
|
{
|
|
286
|
-
if (pHandleX == null || pHandleY == null)
|
|
287
|
-
{
|
|
288
|
-
return this._generateDirectionalPath(pStart, pEnd);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
250
|
let tmpGeo = this._computeDirectionalGeometry(pStart, pEnd);
|
|
292
251
|
|
|
293
|
-
|
|
294
|
-
// First segment: depart -> handle
|
|
295
|
-
// Second segment: handle -> approach
|
|
296
|
-
// Control points are computed to ensure smooth tangent at the handle.
|
|
297
|
-
let tmpCP1aX = tmpGeo.departX + tmpGeo.startDir.dx * ((Math.abs(pHandleX - tmpGeo.departX) + Math.abs(pHandleY - tmpGeo.departY)) * 0.4);
|
|
298
|
-
let tmpCP1aY = tmpGeo.departY + tmpGeo.startDir.dy * ((Math.abs(pHandleX - tmpGeo.departX) + Math.abs(pHandleY - tmpGeo.departY)) * 0.4);
|
|
299
|
-
|
|
300
|
-
// The tangent at the handle should be smooth: the control points on
|
|
301
|
-
// either side of the handle should be collinear through it.
|
|
302
|
-
// Use the direction from depart to approach as the tangent direction.
|
|
303
|
-
let tmpTangentX = tmpGeo.approachX - tmpGeo.departX;
|
|
304
|
-
let tmpTangentY = tmpGeo.approachY - tmpGeo.departY;
|
|
305
|
-
let tmpTangentLen = Math.sqrt(tmpTangentX * tmpTangentX + tmpTangentY * tmpTangentY);
|
|
306
|
-
if (tmpTangentLen < 1) tmpTangentLen = 1;
|
|
307
|
-
let tmpTangentNX = tmpTangentX / tmpTangentLen;
|
|
308
|
-
let tmpTangentNY = tmpTangentY / tmpTangentLen;
|
|
309
|
-
|
|
310
|
-
let tmpTangentScale = tmpTangentLen * 0.2;
|
|
311
|
-
|
|
312
|
-
let tmpCP1bX = pHandleX - tmpTangentNX * tmpTangentScale;
|
|
313
|
-
let tmpCP1bY = pHandleY - tmpTangentNY * tmpTangentScale;
|
|
314
|
-
let tmpCP2aX = pHandleX + tmpTangentNX * tmpTangentScale;
|
|
315
|
-
let tmpCP2aY = pHandleY + tmpTangentNY * tmpTangentScale;
|
|
316
|
-
|
|
317
|
-
let tmpCP2bX = tmpGeo.approachX + tmpGeo.endDir.dx * ((Math.abs(pHandleX - tmpGeo.approachX) + Math.abs(pHandleY - tmpGeo.approachY)) * 0.4);
|
|
318
|
-
let tmpCP2bY = tmpGeo.approachY + tmpGeo.endDir.dy * ((Math.abs(pHandleX - tmpGeo.approachX) + Math.abs(pHandleY - tmpGeo.approachY)) * 0.4);
|
|
319
|
-
|
|
320
|
-
return this._FlowView._PathGenerator.buildSplitBezierPathString(
|
|
252
|
+
return this._FlowView._PathGenerator.buildMultiBezierPathString(
|
|
321
253
|
{ x: pStart.x, y: pStart.y },
|
|
322
254
|
{ x: tmpGeo.departX, y: tmpGeo.departY },
|
|
323
|
-
|
|
324
|
-
{ x: tmpCP1bX, y: tmpCP1bY },
|
|
325
|
-
{ x: pHandleX, y: pHandleY },
|
|
326
|
-
{ x: tmpCP2aX, y: tmpCP2aY },
|
|
327
|
-
{ x: tmpCP2bX, y: tmpCP2bY },
|
|
255
|
+
pHandles,
|
|
328
256
|
{ x: tmpGeo.approachX, y: tmpGeo.approachY },
|
|
329
|
-
{ x: pEnd.x, y: pEnd.y }
|
|
257
|
+
{ x: pEnd.x, y: pEnd.y },
|
|
258
|
+
tmpGeo.startDir,
|
|
259
|
+
tmpGeo.endDir
|
|
330
260
|
);
|
|
331
261
|
}
|
|
332
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Find which segment of the multi-handle bezier the given click point
|
|
265
|
+
* is closest to, returning the index at which a new handle should be
|
|
266
|
+
* inserted into the BezierHandles array.
|
|
267
|
+
*
|
|
268
|
+
* Segments are: depart→handle[0], handle[0]→handle[1], ..., handle[N-1]→approach.
|
|
269
|
+
* Returns 0 for before handle[0], 1 for between handle[0] and handle[1], etc.
|
|
270
|
+
*
|
|
271
|
+
* @param {Array<{x: number, y: number}>} pHandles - Current handles
|
|
272
|
+
* @param {{x: number, y: number}} pClickPoint - Where the user right-clicked
|
|
273
|
+
* @param {{x: number, y: number, side: string}} pStart - Source port position
|
|
274
|
+
* @param {{x: number, y: number, side: string}} pEnd - Target port position
|
|
275
|
+
* @returns {number} Insertion index
|
|
276
|
+
*/
|
|
277
|
+
computeInsertionIndex(pHandles, pClickPoint, pStart, pEnd)
|
|
278
|
+
{
|
|
279
|
+
let tmpGeo = this._computeDirectionalGeometry(pStart, pEnd);
|
|
280
|
+
|
|
281
|
+
// Build the waypoint chain: depart, handle[0..N-1], approach
|
|
282
|
+
let tmpWaypoints = [{ x: tmpGeo.departX, y: tmpGeo.departY }];
|
|
283
|
+
for (let i = 0; i < pHandles.length; i++)
|
|
284
|
+
{
|
|
285
|
+
tmpWaypoints.push(pHandles[i]);
|
|
286
|
+
}
|
|
287
|
+
tmpWaypoints.push({ x: tmpGeo.approachX, y: tmpGeo.approachY });
|
|
288
|
+
|
|
289
|
+
let tmpBestDist = Infinity;
|
|
290
|
+
let tmpBestIndex = 0;
|
|
291
|
+
|
|
292
|
+
for (let i = 0; i < tmpWaypoints.length - 1; i++)
|
|
293
|
+
{
|
|
294
|
+
let tmpDist = this._distanceToSegment(
|
|
295
|
+
pClickPoint.x, pClickPoint.y,
|
|
296
|
+
tmpWaypoints[i].x, tmpWaypoints[i].y,
|
|
297
|
+
tmpWaypoints[i + 1].x, tmpWaypoints[i + 1].y
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
if (tmpDist < tmpBestDist)
|
|
301
|
+
{
|
|
302
|
+
tmpBestDist = tmpDist;
|
|
303
|
+
tmpBestIndex = i;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return tmpBestIndex;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Distance from point (px,py) to line segment (ax,ay)-(bx,by).
|
|
312
|
+
*/
|
|
313
|
+
_distanceToSegment(pPX, pPY, pAX, pAY, pBX, pBY)
|
|
314
|
+
{
|
|
315
|
+
return this._FlowView._PathGenerator.distanceToSegment(pPX, pPY, pAX, pAY, pBX, pBY);
|
|
316
|
+
}
|
|
317
|
+
|
|
333
318
|
/**
|
|
334
319
|
* Get the auto-calculated midpoint of the default bezier curve between two ports.
|
|
335
320
|
* Evaluates the cubic bezier at t=0.5.
|
|
@@ -340,15 +325,7 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
340
325
|
*/
|
|
341
326
|
getAutoMidpoint(pStart, pEnd)
|
|
342
327
|
{
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
return this._FlowView._PathGenerator.evaluateCubicBezier(
|
|
346
|
-
{ x: tmpGeo.departX, y: tmpGeo.departY },
|
|
347
|
-
{ x: tmpGeo.cp1X, y: tmpGeo.cp1Y },
|
|
348
|
-
{ x: tmpGeo.cp2X, y: tmpGeo.cp2Y },
|
|
349
|
-
{ x: tmpGeo.approachX, y: tmpGeo.approachY },
|
|
350
|
-
0.5
|
|
351
|
-
);
|
|
328
|
+
return this._FlowView._PathGenerator.getAutoMidpoint(pStart, pEnd);
|
|
352
329
|
}
|
|
353
330
|
|
|
354
331
|
/**
|
|
@@ -364,16 +341,7 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
364
341
|
*/
|
|
365
342
|
_generateOrthogonalPath(pStart, pEnd, pCorners, pMidOffset)
|
|
366
343
|
{
|
|
367
|
-
let
|
|
368
|
-
let tmpEndDir = this._FlowView._GeometryProvider.sideDirection(pEnd.side || 'left');
|
|
369
|
-
|
|
370
|
-
let tmpStraightLen = 20;
|
|
371
|
-
|
|
372
|
-
let tmpDepartX = pStart.x + tmpStartDir.dx * tmpStraightLen;
|
|
373
|
-
let tmpDepartY = pStart.y + tmpStartDir.dy * tmpStraightLen;
|
|
374
|
-
|
|
375
|
-
let tmpApproachX = pEnd.x + tmpEndDir.dx * tmpStraightLen;
|
|
376
|
-
let tmpApproachY = pEnd.y + tmpEndDir.dy * tmpStraightLen;
|
|
344
|
+
let tmpDA = this._FlowView._PathGenerator.computeDepartApproach(pStart, pEnd, 20);
|
|
377
345
|
|
|
378
346
|
let tmpCorner1, tmpCorner2;
|
|
379
347
|
|
|
@@ -385,9 +353,9 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
385
353
|
else
|
|
386
354
|
{
|
|
387
355
|
let tmpAutoCorners = this._FlowView._PathGenerator.computeAutoOrthogonalCorners(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
356
|
+
tmpDA.departX, tmpDA.departY,
|
|
357
|
+
tmpDA.approachX, tmpDA.approachY,
|
|
358
|
+
tmpDA.fromDir, tmpDA.toDir,
|
|
391
359
|
pMidOffset || 0
|
|
392
360
|
);
|
|
393
361
|
tmpCorner1 = tmpAutoCorners.corner1;
|
|
@@ -396,10 +364,10 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
396
364
|
|
|
397
365
|
return this._FlowView._PathGenerator.buildOrthogonalPathString(
|
|
398
366
|
{ x: pStart.x, y: pStart.y },
|
|
399
|
-
{ x:
|
|
367
|
+
{ x: tmpDA.departX, y: tmpDA.departY },
|
|
400
368
|
tmpCorner1,
|
|
401
369
|
tmpCorner2,
|
|
402
|
-
{ x:
|
|
370
|
+
{ x: tmpDA.approachX, y: tmpDA.approachY },
|
|
403
371
|
{ x: pEnd.x, y: pEnd.y }
|
|
404
372
|
);
|
|
405
373
|
}
|
|
@@ -414,15 +382,7 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
414
382
|
*/
|
|
415
383
|
getOrthogonalGeometry(pStart, pEnd, pData)
|
|
416
384
|
{
|
|
417
|
-
let
|
|
418
|
-
let tmpEndDir = this._FlowView._GeometryProvider.sideDirection(pEnd.side || 'left');
|
|
419
|
-
|
|
420
|
-
let tmpStraightLen = 20;
|
|
421
|
-
|
|
422
|
-
let tmpDepartX = pStart.x + tmpStartDir.dx * tmpStraightLen;
|
|
423
|
-
let tmpDepartY = pStart.y + tmpStartDir.dy * tmpStraightLen;
|
|
424
|
-
let tmpApproachX = pEnd.x + tmpEndDir.dx * tmpStraightLen;
|
|
425
|
-
let tmpApproachY = pEnd.y + tmpEndDir.dy * tmpStraightLen;
|
|
385
|
+
let tmpDA = this._FlowView._PathGenerator.computeDepartApproach(pStart, pEnd, 20);
|
|
426
386
|
|
|
427
387
|
if (pData && pData.HandleCustomized && pData.OrthoCorner1X != null)
|
|
428
388
|
{
|
|
@@ -437,9 +397,9 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
437
397
|
}
|
|
438
398
|
|
|
439
399
|
return this._FlowView._PathGenerator.computeAutoOrthogonalCorners(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
400
|
+
tmpDA.departX, tmpDA.departY,
|
|
401
|
+
tmpDA.approachX, tmpDA.approachY,
|
|
402
|
+
tmpDA.fromDir, tmpDA.toDir,
|
|
443
403
|
(pData && pData.OrthoMidOffset) || 0
|
|
444
404
|
);
|
|
445
405
|
}
|
|
@@ -475,19 +435,26 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
475
435
|
}
|
|
476
436
|
else
|
|
477
437
|
{
|
|
478
|
-
// Bezier
|
|
479
|
-
|
|
480
|
-
|
|
438
|
+
// Bezier handles — show one handle per waypoint, or a
|
|
439
|
+
// single auto-midpoint when no custom handles exist.
|
|
440
|
+
let tmpHandles = this._getBezierHandles(tmpData);
|
|
441
|
+
|
|
442
|
+
if (tmpHandles.length > 0)
|
|
481
443
|
{
|
|
482
|
-
|
|
444
|
+
for (let i = 0; i < tmpHandles.length; i++)
|
|
445
|
+
{
|
|
446
|
+
this._createHandle(pLayer, pConnection.Hash,
|
|
447
|
+
'bezier-handle-' + i,
|
|
448
|
+
tmpHandles[i].x, tmpHandles[i].y,
|
|
449
|
+
'pict-flow-connection-handle');
|
|
450
|
+
}
|
|
483
451
|
}
|
|
484
452
|
else
|
|
485
453
|
{
|
|
486
|
-
tmpMidpoint = this.getAutoMidpoint(pStart, pEnd);
|
|
454
|
+
let tmpMidpoint = this.getAutoMidpoint(pStart, pEnd);
|
|
455
|
+
this._createHandle(pLayer, pConnection.Hash, 'bezier-midpoint',
|
|
456
|
+
tmpMidpoint.x, tmpMidpoint.y, 'pict-flow-connection-handle');
|
|
487
457
|
}
|
|
488
|
-
|
|
489
|
-
this._createHandle(pLayer, pConnection.Hash, 'bezier-midpoint',
|
|
490
|
-
tmpMidpoint.x, tmpMidpoint.y, 'pict-flow-connection-handle');
|
|
491
458
|
}
|
|
492
459
|
}
|
|
493
460
|
|
|
@@ -503,30 +470,14 @@ class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
|
|
|
503
470
|
*/
|
|
504
471
|
_createHandle(pLayer, pConnectionHash, pHandleType, pX, pY, pClassName)
|
|
505
472
|
{
|
|
506
|
-
|
|
473
|
+
if (!this._FlowView._ConnectorShapesProvider) return;
|
|
474
|
+
|
|
507
475
|
let tmpShapeKey = (pClassName === 'pict-flow-connection-handle-midpoint')
|
|
508
476
|
? 'connection-handle-midpoint' : 'connection-handle';
|
|
509
477
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
pConnectionHash, pHandleType, pX, pY, tmpShapeKey);
|
|
514
|
-
tmpHandle.setAttribute('data-element-type', 'connection-handle');
|
|
515
|
-
tmpHandle.setAttribute('data-connection-hash', pConnectionHash);
|
|
516
|
-
pLayer.appendChild(tmpHandle);
|
|
517
|
-
}
|
|
518
|
-
else
|
|
519
|
-
{
|
|
520
|
-
let tmpCircle = this._FlowView._SVGHelperProvider.createSVGElement('circle');
|
|
521
|
-
tmpCircle.setAttribute('class', pClassName);
|
|
522
|
-
tmpCircle.setAttribute('cx', String(pX));
|
|
523
|
-
tmpCircle.setAttribute('cy', String(pY));
|
|
524
|
-
tmpCircle.setAttribute('r', '6');
|
|
525
|
-
tmpCircle.setAttribute('data-element-type', 'connection-handle');
|
|
526
|
-
tmpCircle.setAttribute('data-connection-hash', pConnectionHash);
|
|
527
|
-
tmpCircle.setAttribute('data-handle-type', pHandleType);
|
|
528
|
-
pLayer.appendChild(tmpCircle);
|
|
529
|
-
}
|
|
478
|
+
this._FlowView._ConnectorShapesProvider.createFullHandle(
|
|
479
|
+
pLayer, pConnectionHash, pHandleType, pX, pY,
|
|
480
|
+
tmpShapeKey, 'connection-handle', 'data-connection-hash');
|
|
530
481
|
}
|
|
531
482
|
|
|
532
483
|
/**
|