pict-section-flow 1.4.0 → 2.0.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/package.json +7 -2
- package/source/Pict-Section-Flow.js +20 -14
- package/source/providers/PictProvider-Flow-Background.js +303 -0
- package/source/providers/PictProvider-Flow-CSS.js +73 -7
- package/source/providers/PictProvider-Flow-Geometry.js +11 -421
- package/source/providers/PictProvider-Flow-Icons.js +12 -0
- package/source/providers/PictProvider-Flow-Layouts.js +107 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +1 -1
- package/source/services/PictService-Flow-CursorManager.js +113 -0
- package/source/services/PictService-Flow-InteractionManager.js +439 -59
- package/source/services/PictService-Flow-Layout.js +21 -16
- package/source/services/PictService-Flow-PathGenerator.js +30 -417
- package/source/services/PictService-Flow-RenderManager.js +9 -1
- package/source/services/PictService-Flow-ViewportManager.js +102 -0
- package/source/views/PictView-Flow-FloatingToolbar.js +5 -1
- package/source/views/PictView-Flow-Node.js +29 -0
- package/source/views/PictView-Flow-Toolbar.js +50 -3
- package/source/views/PictView-Flow.js +591 -2
- package/.claude/launch.json +0 -11
- package/docs/.nojekyll +0 -0
- package/docs/Architecture.md +0 -163
- package/docs/Custom-Styling.md +0 -275
- package/docs/Data_Model.md +0 -149
- package/docs/Event_System.md +0 -156
- package/docs/Getting_Started.md +0 -237
- package/docs/Implementation_Reference.md +0 -528
- package/docs/Layout_Persistence.md +0 -117
- package/docs/README.md +0 -103
- package/docs/Theme_Integration.md +0 -150
- package/docs/_brand.json +0 -18
- package/docs/_cover.md +0 -17
- package/docs/_playground.json +0 -24
- package/docs/_sidebar.md +0 -57
- package/docs/_topbar.md +0 -8
- package/docs/_version.json +0 -7
- package/docs/api/PictFlowCard.md +0 -216
- package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
- package/docs/api/addConnection.md +0 -101
- package/docs/api/addNode.md +0 -137
- package/docs/api/autoLayout.md +0 -77
- package/docs/api/getFlowData.md +0 -112
- package/docs/api/marshalToView.md +0 -95
- package/docs/api/openPanel.md +0 -128
- package/docs/api/registerHandler.md +0 -174
- package/docs/api/registerNodeType.md +0 -142
- package/docs/api/removeConnection.md +0 -57
- package/docs/api/removeNode.md +0 -80
- package/docs/api/saveLayout.md +0 -152
- package/docs/api/screenToSVGCoords.md +0 -68
- package/docs/api/selectNode.md +0 -116
- package/docs/api/setTheme.md +0 -168
- package/docs/api/setZoom.md +0 -97
- package/docs/api/toggleFullscreen.md +0 -68
- package/docs/card-help/EACH.md +0 -19
- package/docs/card-help/FREAD.md +0 -24
- package/docs/card-help/FWRITE.md +0 -24
- package/docs/card-help/GET.md +0 -22
- package/docs/card-help/ITE.md +0 -23
- package/docs/card-help/LOG.md +0 -23
- package/docs/card-help/NOTE.md +0 -17
- package/docs/card-help/PREV.md +0 -18
- package/docs/card-help/SET.md +0 -27
- package/docs/card-help/SPKL.md +0 -22
- package/docs/card-help/STAT.md +0 -23
- package/docs/card-help/SW.md +0 -25
- package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
- package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
- package/docs/diagrams/architecture-at-a-glance.svg +0 -2
- package/docs/diagrams/data-flow.excalidraw +0 -1451
- package/docs/diagrams/data-flow.mmd +0 -17
- package/docs/diagrams/data-flow.svg +0 -2
- package/docs/diagrams/high-level-design.excalidraw +0 -5767
- package/docs/diagrams/high-level-design.mmd +0 -86
- package/docs/diagrams/high-level-design.svg +0 -2
- package/docs/diagrams/relationships.excalidraw +0 -3852
- package/docs/diagrams/relationships.mmd +0 -9
- package/docs/diagrams/relationships.svg +0 -2
- package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
- package/docs/diagrams/service-initialization-sequence.mmd +0 -19
- package/docs/diagrams/service-initialization-sequence.svg +0 -2
- package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
- package/docs/diagrams/svg-layer-structure.mmd +0 -18
- package/docs/diagrams/svg-layer-structure.svg +0 -2
- package/docs/examples/README.md +0 -9
- package/docs/examples/simple_cards/README.md +0 -677
- package/docs/examples/simple_cards/css/flowexample.css +0 -65
- package/docs/examples/simple_cards/index.html +0 -32
- package/docs/examples/simple_cards/js/pict.min.js +0 -12
- package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
- package/docs/index.html +0 -38
- package/docs/playground/app.json +0 -6
- package/docs/playground/appdata.json +0 -85
- package/docs/playground/application.js +0 -23
- package/docs/playground/pict.json +0 -17
- package/docs/playground/runtime/pict-application.min.js +0 -2
- package/docs/playground/runtime/pict-section-flow.min.js +0 -2
- package/docs/playground/runtime/pict-section-modal.min.js +0 -2
- package/docs/playground/runtime/pict.min.js +0 -12
- package/docs/retold-catalog.json +0 -244
- package/docs/retold-keyword-index.json +0 -26028
- package/example_applications/simple_cards/css/flowexample.css +0 -65
- package/example_applications/simple_cards/html/index.html +0 -32
- package/example_applications/simple_cards/package.json +0 -52
- package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
- package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
- package/example_applications/simple_cards/source/card-help-content.js +0 -16
- package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
- package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
- package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
- package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
- package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
- package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
- package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
- package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
- package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
- package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
- package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
- package/example_applications/simple_cards/source/sample-flows.js +0 -410
- package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
- package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
- package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
- package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
- package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
- package/scripts/generate-card-help.js +0 -214
- package/source/providers/edges/Edge-Bezier.js +0 -41
- package/source/providers/edges/Edge-Orthogonal.js +0 -37
- package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
- package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
- package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
- package/source/providers/edges/Edge-Perimeter.js +0 -48
- package/source/providers/edges/Edge-PerimeterMath.js +0 -92
- package/source/providers/edges/Edge-Straight.js +0 -24
- package/source/providers/layouts/Layout-Circular.js +0 -203
- package/source/providers/layouts/Layout-Coerce.js +0 -40
- package/source/providers/layouts/Layout-Columnar.js +0 -134
- package/source/providers/layouts/Layout-Custom.js +0 -27
- package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
- package/source/providers/layouts/Layout-Grid.js +0 -134
- package/source/providers/layouts/Layout-Layered.js +0 -155
- package/source/providers/layouts/Layout-Rank.js +0 -141
- package/source/providers/layouts/Layout-Staggered.js +0 -131
- package/source/providers/layouts/Layout-Tabular.js +0 -94
- package/test/CardPalette_tests.js +0 -43
- package/test/ConnectionHandleManager_tests.js +0 -717
- package/test/ConnectionRenderer_tests.js +0 -591
- package/test/ConnectionStyle_tests.js +0 -90
- package/test/DataManager_tests.js +0 -859
- package/test/Geometry_tests.js +0 -767
- package/test/InteractionManager_tests.js +0 -279
- package/test/Layout_tests.js +0 -1604
- package/test/NodeView_tests.js +0 -66
- package/test/PanelManager_tests.js +0 -172
- package/test/PathGenerator_tests.js +0 -978
- package/test/PortRenderer_tests.js +0 -376
- package/test/RenderManager_tests.js +0 -756
- package/test/Renderer_tests.js +0 -133
- package/test/SelectionManager_tests.js +0 -185
- package/test/StylePresets_tests.js +0 -153
- package/test/ToolbarExtraButtons_tests.js +0 -138
- package/test/UndirectedConnections_tests.js +0 -70
|
@@ -13,6 +13,9 @@ const INTERACTION_STATES =
|
|
|
13
13
|
PANNING: 'panning',
|
|
14
14
|
RESIZING_PANEL: 'resizing-panel',
|
|
15
15
|
RESIZING_NODE: 'resizing-node',
|
|
16
|
+
ROTATING_NODE: 'rotating-node',
|
|
17
|
+
RESIZING_FRAME: 'resizing-frame',
|
|
18
|
+
MOVING_FRAME: 'moving-frame',
|
|
16
19
|
MARQUEE: 'marquee'
|
|
17
20
|
};
|
|
18
21
|
|
|
@@ -30,7 +33,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
30
33
|
this._ViewportElement = null;
|
|
31
34
|
|
|
32
35
|
// Interaction state
|
|
33
|
-
this.
|
|
36
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
34
37
|
|
|
35
38
|
// Drag state
|
|
36
39
|
this._DragNodeHash = null;
|
|
@@ -80,6 +83,13 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
80
83
|
this._ResizeNodeStartWidth = 0;
|
|
81
84
|
this._ResizeNodeStartHeight = 0;
|
|
82
85
|
|
|
86
|
+
// Content-frame edit state (drag the frame's edge handles to resize, or its move
|
|
87
|
+
// handle to reposition the view-area box).
|
|
88
|
+
this._FrameDragEdge = null;
|
|
89
|
+
this._FrameStart = null;
|
|
90
|
+
this._FrameStartPointerX = 0;
|
|
91
|
+
this._FrameStartPointerY = 0;
|
|
92
|
+
|
|
83
93
|
// Double-click detection for connections
|
|
84
94
|
this._LastConnectionClickTime = 0;
|
|
85
95
|
this._LastConnectionClickHash = null;
|
|
@@ -133,6 +143,9 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
133
143
|
{
|
|
134
144
|
pEvent.preventDefault();
|
|
135
145
|
|
|
146
|
+
// No edge/handle editing in read-only mode.
|
|
147
|
+
if (this._isReadOnly()) return;
|
|
148
|
+
|
|
136
149
|
let tmpTarget = pEvent.target;
|
|
137
150
|
let tmpElementType = this._getElementType(tmpTarget);
|
|
138
151
|
|
|
@@ -168,6 +181,53 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
168
181
|
document.removeEventListener('keydown', this._boundOnKeyDown);
|
|
169
182
|
}
|
|
170
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Whether the flow is in read-only / presentation mode. Tolerant of minimal
|
|
186
|
+
* test harnesses: prefers the view's isReadOnly(), falls back to the option.
|
|
187
|
+
* @returns {boolean}
|
|
188
|
+
*/
|
|
189
|
+
_isReadOnly()
|
|
190
|
+
{
|
|
191
|
+
if (!this._FlowView) return false;
|
|
192
|
+
if (typeof this._FlowView.isReadOnly === 'function') return !!this._FlowView.isReadOnly();
|
|
193
|
+
return !!(this._FlowView.options && this._FlowView.options.ReadOnly);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Whether read-only canvas navigation (pan + wheel-zoom) is currently on (the
|
|
198
|
+
* "hand" toggle). When off, a read-only canvas is static and the wheel scrolls
|
|
199
|
+
* the page.
|
|
200
|
+
* @returns {boolean}
|
|
201
|
+
*/
|
|
202
|
+
_isReadOnlyNavigating()
|
|
203
|
+
{
|
|
204
|
+
return !!(this._FlowView && typeof this._FlowView.isReadOnlyNavigation === 'function' && this._FlowView.isReadOnlyNavigation());
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The single interaction-state transition chokepoint. Setting state here keeps
|
|
209
|
+
* the canvas cursor (and any future state-derived concern) an intentional,
|
|
210
|
+
* derived property rather than something toggled by hand at each call site.
|
|
211
|
+
* @param {string} pState - an INTERACTION_STATES value
|
|
212
|
+
*/
|
|
213
|
+
_setState(pState)
|
|
214
|
+
{
|
|
215
|
+
this._State = pState;
|
|
216
|
+
this._updateCursor();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Ask the CursorManager to re-derive the canvas cursor from the current state
|
|
221
|
+
* and mode. No-op until the CursorManager and SVG element exist.
|
|
222
|
+
*/
|
|
223
|
+
_updateCursor()
|
|
224
|
+
{
|
|
225
|
+
if (this._FlowView && this._FlowView._CursorManager)
|
|
226
|
+
{
|
|
227
|
+
this._FlowView._CursorManager.update();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
171
231
|
/**
|
|
172
232
|
* Handle pointer down event
|
|
173
233
|
* @param {PointerEvent} pEvent
|
|
@@ -192,6 +252,59 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
192
252
|
this._SVGElement.setPointerCapture(pEvent.pointerId);
|
|
193
253
|
}
|
|
194
254
|
|
|
255
|
+
// Read-only / presentation mode: a reduced dispatch. Selection, node
|
|
256
|
+
// activation (so a host can open a read-only inspector), and panning are
|
|
257
|
+
// allowed; every editing interaction (drag, resize, connect, handle add,
|
|
258
|
+
// panel edit) is inert.
|
|
259
|
+
if (this._isReadOnly())
|
|
260
|
+
{
|
|
261
|
+
// Hand tool on (navigation enabled): a drag anywhere grabs and pans the canvas, including
|
|
262
|
+
// over a card — you are moving the viewport, like the Photoshop hand. No selection here.
|
|
263
|
+
if (this._isReadOnlyNavigating())
|
|
264
|
+
{
|
|
265
|
+
if (pEvent.button === 0 && this._FlowView.options.EnablePanning)
|
|
266
|
+
{
|
|
267
|
+
this._startPanning(pEvent);
|
|
268
|
+
}
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Hand off (static): selection + node activation for inspection; the canvas does not move.
|
|
273
|
+
switch (tmpElementType)
|
|
274
|
+
{
|
|
275
|
+
case 'node':
|
|
276
|
+
case 'node-body':
|
|
277
|
+
case 'panel-indicator':
|
|
278
|
+
{
|
|
279
|
+
let tmpNodeHash = this._getNodeHash(tmpTarget);
|
|
280
|
+
if (tmpNodeHash)
|
|
281
|
+
{
|
|
282
|
+
this._FlowView.selectNode(tmpNodeHash);
|
|
283
|
+
let tmpNode = this._FlowView.getNode(tmpNodeHash);
|
|
284
|
+
if (tmpNode && this._FlowView._EventHandlerProvider)
|
|
285
|
+
{
|
|
286
|
+
this._FlowView._EventHandlerProvider.fireEvent('onNodeActivate', tmpNode);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
case 'connection':
|
|
293
|
+
case 'connection-hitarea':
|
|
294
|
+
this._selectConnection(tmpTarget);
|
|
295
|
+
break;
|
|
296
|
+
|
|
297
|
+
case 'tether':
|
|
298
|
+
case 'tether-hitarea':
|
|
299
|
+
this._selectTether(tmpTarget);
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
default:
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
195
308
|
switch (tmpElementType)
|
|
196
309
|
{
|
|
197
310
|
case 'port':
|
|
@@ -245,6 +358,18 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
245
358
|
this._startNodeResize(pEvent, tmpTarget);
|
|
246
359
|
break;
|
|
247
360
|
|
|
361
|
+
case 'node-rotate':
|
|
362
|
+
this._startNodeRotate(pEvent, tmpTarget);
|
|
363
|
+
break;
|
|
364
|
+
|
|
365
|
+
case 'frame-resize':
|
|
366
|
+
this._startFrameResize(pEvent, tmpTarget);
|
|
367
|
+
break;
|
|
368
|
+
|
|
369
|
+
case 'frame-move':
|
|
370
|
+
this._startFrameMove(pEvent, tmpTarget);
|
|
371
|
+
break;
|
|
372
|
+
|
|
248
373
|
case 'panel-close':
|
|
249
374
|
{
|
|
250
375
|
let tmpPanelHash = this._getPanelHash(tmpTarget);
|
|
@@ -417,6 +542,18 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
417
542
|
this._onNodeResize(pEvent);
|
|
418
543
|
break;
|
|
419
544
|
|
|
545
|
+
case INTERACTION_STATES.RESIZING_FRAME:
|
|
546
|
+
this._onFrameResize(pEvent);
|
|
547
|
+
break;
|
|
548
|
+
|
|
549
|
+
case INTERACTION_STATES.MOVING_FRAME:
|
|
550
|
+
this._onFrameMove(pEvent);
|
|
551
|
+
break;
|
|
552
|
+
|
|
553
|
+
case INTERACTION_STATES.ROTATING_NODE:
|
|
554
|
+
this._onNodeRotate(pEvent);
|
|
555
|
+
break;
|
|
556
|
+
|
|
420
557
|
case INTERACTION_STATES.PANNING:
|
|
421
558
|
this._onPan(pEvent);
|
|
422
559
|
break;
|
|
@@ -463,6 +600,15 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
463
600
|
this._endNodeResize(pEvent);
|
|
464
601
|
break;
|
|
465
602
|
|
|
603
|
+
case INTERACTION_STATES.RESIZING_FRAME:
|
|
604
|
+
case INTERACTION_STATES.MOVING_FRAME:
|
|
605
|
+
this._endFrameEdit(pEvent);
|
|
606
|
+
break;
|
|
607
|
+
|
|
608
|
+
case INTERACTION_STATES.ROTATING_NODE:
|
|
609
|
+
this._endNodeRotate(pEvent);
|
|
610
|
+
break;
|
|
611
|
+
|
|
466
612
|
case INTERACTION_STATES.CONNECTING:
|
|
467
613
|
this._endConnection(pEvent);
|
|
468
614
|
break;
|
|
@@ -478,24 +624,98 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
478
624
|
}
|
|
479
625
|
|
|
480
626
|
/**
|
|
481
|
-
*
|
|
627
|
+
* Decide what a wheel event should do, from config and modifier keys. Pure
|
|
628
|
+
* (no DOM, no side effects) so it is unit testable.
|
|
629
|
+
*
|
|
630
|
+
* WheelMode 'zoom' (default): wheel zooms; if WheelZoomRequiresModifier is on,
|
|
631
|
+
* a plain wheel pans and ctrl/cmd+wheel zooms.
|
|
632
|
+
* WheelMode 'pan': wheel pans; ctrl/cmd+wheel zooms.
|
|
633
|
+
* WheelMode 'none': flow ignores the wheel (page scrolls).
|
|
634
|
+
*
|
|
635
|
+
* Zoom is gated by EnableZooming and pan by EnablePanning; when the intended
|
|
636
|
+
* action is disabled the result is 'none' (matching the legacy early return
|
|
637
|
+
* when zooming was off).
|
|
638
|
+
*
|
|
639
|
+
* @param {WheelEvent} pEvent
|
|
640
|
+
* @returns {{action: string}} action is 'zoom' | 'pan' | 'none'
|
|
641
|
+
*/
|
|
642
|
+
_resolveWheelAction(pEvent)
|
|
643
|
+
{
|
|
644
|
+
let tmpOptions = (this._FlowView && this._FlowView.options) ? this._FlowView.options : {};
|
|
645
|
+
|
|
646
|
+
// Read-only has its own wheel policy: by default the wheel scrolls the page
|
|
647
|
+
// (the canvas is static content); only when navigation is toggled on (the
|
|
648
|
+
// hand toggle) does the wheel zoom the canvas.
|
|
649
|
+
if (this._isReadOnly())
|
|
650
|
+
{
|
|
651
|
+
return { action: this._isReadOnlyNavigating() ? 'zoom' : 'none' };
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
let tmpWheelMode = tmpOptions.WheelMode || 'zoom';
|
|
655
|
+
|
|
656
|
+
if (tmpWheelMode === 'none')
|
|
657
|
+
{
|
|
658
|
+
return { action: 'none' };
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
let tmpModifier = !!(pEvent && (pEvent.ctrlKey || pEvent.metaKey));
|
|
662
|
+
|
|
663
|
+
let tmpWantZoom;
|
|
664
|
+
if (tmpWheelMode === 'pan')
|
|
665
|
+
{
|
|
666
|
+
tmpWantZoom = tmpModifier;
|
|
667
|
+
}
|
|
668
|
+
else
|
|
669
|
+
{
|
|
670
|
+
tmpWantZoom = tmpOptions.WheelZoomRequiresModifier ? tmpModifier : true;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (tmpWantZoom)
|
|
674
|
+
{
|
|
675
|
+
return { action: tmpOptions.EnableZooming ? 'zoom' : 'none' };
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return { action: (tmpOptions.EnablePanning === false) ? 'none' : 'pan' };
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Handle mouse wheel: zoom toward the pointer, pan the canvas, or ignore,
|
|
683
|
+
* per _resolveWheelAction.
|
|
482
684
|
* @param {WheelEvent} pEvent
|
|
483
685
|
*/
|
|
484
686
|
_onWheel(pEvent)
|
|
485
687
|
{
|
|
486
|
-
if (!this._FlowView
|
|
688
|
+
if (!this._FlowView) return;
|
|
689
|
+
|
|
690
|
+
let tmpResolved = this._resolveWheelAction(pEvent);
|
|
691
|
+
if (tmpResolved.action === 'none') return;
|
|
487
692
|
|
|
488
693
|
pEvent.preventDefault();
|
|
489
694
|
|
|
490
|
-
let
|
|
491
|
-
let tmpNewZoom = this._FlowView.viewState.Zoom + tmpDelta;
|
|
695
|
+
let tmpOptions = this._FlowView.options;
|
|
492
696
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
697
|
+
if (tmpResolved.action === 'zoom')
|
|
698
|
+
{
|
|
699
|
+
let tmpSensitivity = (typeof tmpOptions.WheelZoomSensitivity === 'number') ? tmpOptions.WheelZoomSensitivity : 1;
|
|
700
|
+
let tmpStep = tmpOptions.ZoomStep * tmpSensitivity;
|
|
701
|
+
let tmpDelta = pEvent.deltaY > 0 ? -tmpStep : tmpStep;
|
|
702
|
+
let tmpNewZoom = this._FlowView.viewState.Zoom + tmpDelta;
|
|
703
|
+
|
|
704
|
+
// Zoom toward mouse position
|
|
705
|
+
let tmpRect = this._SVGElement.getBoundingClientRect();
|
|
706
|
+
let tmpMouseX = pEvent.clientX - tmpRect.left;
|
|
707
|
+
let tmpMouseY = pEvent.clientY - tmpRect.top;
|
|
497
708
|
|
|
498
|
-
|
|
709
|
+
this._FlowView.setZoom(tmpNewZoom, tmpMouseX, tmpMouseY);
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Pan: wheel scrolls the canvas. Shift+wheel commonly arrives as deltaX.
|
|
714
|
+
let tmpPanSensitivity = (typeof tmpOptions.WheelPanSensitivity === 'number') ? tmpOptions.WheelPanSensitivity : 1;
|
|
715
|
+
if (this._FlowView._ViewportManager && typeof this._FlowView._ViewportManager.panBy === 'function')
|
|
716
|
+
{
|
|
717
|
+
this._FlowView._ViewportManager.panBy(-pEvent.deltaX * tmpPanSensitivity, -pEvent.deltaY * tmpPanSensitivity);
|
|
718
|
+
}
|
|
499
719
|
}
|
|
500
720
|
|
|
501
721
|
/**
|
|
@@ -509,6 +729,9 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
509
729
|
// Only handle events when the flow is focused/visible
|
|
510
730
|
if (pEvent.key === 'Delete' || pEvent.key === 'Backspace')
|
|
511
731
|
{
|
|
732
|
+
// No deletion in read-only mode.
|
|
733
|
+
if (this._isReadOnly()) return;
|
|
734
|
+
|
|
512
735
|
// Don't delete if user is typing in an input or inside a panel
|
|
513
736
|
if (pEvent.target && (pEvent.target.tagName === 'INPUT' || pEvent.target.tagName === 'TEXTAREA' || pEvent.target.tagName === 'SELECT'))
|
|
514
737
|
{
|
|
@@ -579,13 +802,11 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
579
802
|
}
|
|
580
803
|
if (this._DragNodes.length === 0) return;
|
|
581
804
|
|
|
582
|
-
this.
|
|
805
|
+
this._setState(INTERACTION_STATES.DRAGGING_NODE);
|
|
583
806
|
this._DragNodeHash = tmpNodeHash;
|
|
584
807
|
this._DragStartX = pEvent.clientX;
|
|
585
808
|
this._DragStartY = pEvent.clientY;
|
|
586
809
|
|
|
587
|
-
this._SVGElement.classList.add('panning');
|
|
588
|
-
|
|
589
810
|
for (let i = 0; i < this._DragNodes.length; i++)
|
|
590
811
|
{
|
|
591
812
|
let tmpNodeGroup = this._FlowView._NodesLayer.querySelector(`[data-node-hash="${this._DragNodes[i].Hash}"]`);
|
|
@@ -735,9 +956,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
735
956
|
}
|
|
736
957
|
|
|
737
958
|
_endNodeDrag(pEvent)
|
|
738
|
-
{
|
|
739
|
-
this._SVGElement.classList.remove('panning');
|
|
740
|
-
this._clearGuides();
|
|
959
|
+
{ this._clearGuides();
|
|
741
960
|
|
|
742
961
|
let tmpDragged = this._DragNodes || [];
|
|
743
962
|
for (let i = 0; i < tmpDragged.length; i++)
|
|
@@ -759,7 +978,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
759
978
|
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
760
979
|
}
|
|
761
980
|
|
|
762
|
-
this.
|
|
981
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
763
982
|
this._DragNodeHash = null;
|
|
764
983
|
this._DragNodes = null;
|
|
765
984
|
}
|
|
@@ -774,14 +993,12 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
774
993
|
let tmpPanel = this._FlowView._FlowData.OpenPanels.find((pPanel) => pPanel.Hash === tmpPanelHash);
|
|
775
994
|
if (!tmpPanel) return;
|
|
776
995
|
|
|
777
|
-
this.
|
|
996
|
+
this._setState(INTERACTION_STATES.DRAGGING_PANEL);
|
|
778
997
|
this._DragPanelHash = tmpPanelHash;
|
|
779
998
|
this._DragPanelStartX = pEvent.clientX;
|
|
780
999
|
this._DragPanelStartY = pEvent.clientY;
|
|
781
1000
|
this._DragPanelDataStartX = tmpPanel.X;
|
|
782
1001
|
this._DragPanelDataStartY = tmpPanel.Y;
|
|
783
|
-
|
|
784
|
-
this._SVGElement.classList.add('panning');
|
|
785
1002
|
}
|
|
786
1003
|
|
|
787
1004
|
_onPanelDrag(pEvent)
|
|
@@ -800,8 +1017,6 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
800
1017
|
|
|
801
1018
|
_endPanelDrag(pEvent)
|
|
802
1019
|
{
|
|
803
|
-
this._SVGElement.classList.remove('panning');
|
|
804
|
-
|
|
805
1020
|
this._FlowView.marshalFromView();
|
|
806
1021
|
|
|
807
1022
|
let tmpPanel = this._FlowView._FlowData.OpenPanels.find((pPanel) => pPanel.Hash === this._DragPanelHash);
|
|
@@ -811,7 +1026,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
811
1026
|
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
812
1027
|
}
|
|
813
1028
|
|
|
814
|
-
this.
|
|
1029
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
815
1030
|
this._DragPanelHash = null;
|
|
816
1031
|
}
|
|
817
1032
|
|
|
@@ -825,12 +1040,10 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
825
1040
|
let tmpPanel = this._FlowView._FlowData.OpenPanels.find((pPanel) => pPanel.Hash === tmpPanelHash);
|
|
826
1041
|
if (!tmpPanel) return;
|
|
827
1042
|
|
|
828
|
-
this.
|
|
1043
|
+
this._setState(INTERACTION_STATES.RESIZING_PANEL);
|
|
829
1044
|
this._ResizePanelHash = tmpPanelHash;
|
|
830
1045
|
this._ResizeStartY = pEvent.clientY;
|
|
831
1046
|
this._ResizePanelStartHeight = tmpPanel.Height;
|
|
832
|
-
|
|
833
|
-
this._SVGElement.classList.add('panning');
|
|
834
1047
|
}
|
|
835
1048
|
|
|
836
1049
|
_onPanelResize(pEvent)
|
|
@@ -861,8 +1074,6 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
861
1074
|
|
|
862
1075
|
_endPanelResize(pEvent)
|
|
863
1076
|
{
|
|
864
|
-
this._SVGElement.classList.remove('panning');
|
|
865
|
-
|
|
866
1077
|
// Re-render to sync tethers
|
|
867
1078
|
this._FlowView.renderFlow();
|
|
868
1079
|
this._FlowView.marshalFromView();
|
|
@@ -872,7 +1083,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
872
1083
|
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
873
1084
|
}
|
|
874
1085
|
|
|
875
|
-
this.
|
|
1086
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
876
1087
|
this._ResizePanelHash = null;
|
|
877
1088
|
}
|
|
878
1089
|
|
|
@@ -891,14 +1102,12 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
891
1102
|
let tmpNode = this._FlowView.getNode(tmpNodeHash);
|
|
892
1103
|
if (!tmpNode) return;
|
|
893
1104
|
|
|
894
|
-
this.
|
|
1105
|
+
this._setState(INTERACTION_STATES.RESIZING_NODE);
|
|
895
1106
|
this._ResizeNodeHash = tmpNodeHash;
|
|
896
1107
|
this._ResizeNodeStartX = pEvent.clientX;
|
|
897
1108
|
this._ResizeNodeStartY = pEvent.clientY;
|
|
898
1109
|
this._ResizeNodeStartWidth = tmpNode.Width || 180;
|
|
899
1110
|
this._ResizeNodeStartHeight = tmpNode.Height || 80;
|
|
900
|
-
|
|
901
|
-
this._SVGElement.classList.add('panning');
|
|
902
1111
|
if (pEvent.stopPropagation) pEvent.stopPropagation();
|
|
903
1112
|
}
|
|
904
1113
|
|
|
@@ -925,8 +1134,6 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
925
1134
|
|
|
926
1135
|
_endNodeResize(pEvent)
|
|
927
1136
|
{
|
|
928
|
-
this._SVGElement.classList.remove('panning');
|
|
929
|
-
|
|
930
1137
|
this._FlowView.renderFlow();
|
|
931
1138
|
this._FlowView.marshalFromView();
|
|
932
1139
|
|
|
@@ -937,23 +1144,208 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
937
1144
|
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
938
1145
|
}
|
|
939
1146
|
|
|
940
|
-
this.
|
|
1147
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
941
1148
|
this._ResizeNodeHash = null;
|
|
942
1149
|
}
|
|
943
1150
|
|
|
1151
|
+
// ---- Content-frame editing (drag the view-area box) ----
|
|
1152
|
+
|
|
1153
|
+
_startFrameResize(pEvent, pTarget)
|
|
1154
|
+
{
|
|
1155
|
+
if (!this._FlowView.options.EnableFrameEditing) return;
|
|
1156
|
+
let tmpFrame = this._FlowView._resolveFrame();
|
|
1157
|
+
if (!tmpFrame) return;
|
|
1158
|
+
|
|
1159
|
+
this._setState(INTERACTION_STATES.RESIZING_FRAME);
|
|
1160
|
+
this._FrameDragEdge = (pTarget && pTarget.getAttribute) ? pTarget.getAttribute('data-frame-edge') : null;
|
|
1161
|
+
this._FrameStart = { X: tmpFrame.X || 0, Y: tmpFrame.Y || 0, Width: tmpFrame.Width, Height: tmpFrame.Height };
|
|
1162
|
+
this._FrameStartPointerX = pEvent.clientX;
|
|
1163
|
+
this._FrameStartPointerY = pEvent.clientY;
|
|
1164
|
+
if (pEvent.stopPropagation) pEvent.stopPropagation();
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
_startFrameMove(pEvent, pTarget)
|
|
1168
|
+
{
|
|
1169
|
+
if (!this._FlowView.options.EnableFrameEditing) return;
|
|
1170
|
+
let tmpFrame = this._FlowView._resolveFrame();
|
|
1171
|
+
if (!tmpFrame) return;
|
|
1172
|
+
|
|
1173
|
+
this._setState(INTERACTION_STATES.MOVING_FRAME);
|
|
1174
|
+
this._FrameStart = { X: tmpFrame.X || 0, Y: tmpFrame.Y || 0, Width: tmpFrame.Width, Height: tmpFrame.Height };
|
|
1175
|
+
this._FrameStartPointerX = pEvent.clientX;
|
|
1176
|
+
this._FrameStartPointerY = pEvent.clientY;
|
|
1177
|
+
if (pEvent.stopPropagation) pEvent.stopPropagation();
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
_onFrameResize(pEvent)
|
|
1181
|
+
{
|
|
1182
|
+
if (!this._FrameStart) return;
|
|
1183
|
+
let tmpVS = this._FlowView.viewState;
|
|
1184
|
+
let tmpDX = (pEvent.clientX - this._FrameStartPointerX) / tmpVS.Zoom;
|
|
1185
|
+
let tmpDY = (pEvent.clientY - this._FrameStartPointerY) / tmpVS.Zoom;
|
|
1186
|
+
let tmpMin = this._FlowView.options.MinimumFrameSize || 40;
|
|
1187
|
+
this._applyFrameEdit(PictServiceFlowInteractionManager.computeFrameResize(this._FrameStart, this._FrameDragEdge, tmpDX, tmpDY, tmpMin));
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
_onFrameMove(pEvent)
|
|
1191
|
+
{
|
|
1192
|
+
if (!this._FrameStart) return;
|
|
1193
|
+
let tmpVS = this._FlowView.viewState;
|
|
1194
|
+
let tmpDX = (pEvent.clientX - this._FrameStartPointerX) / tmpVS.Zoom;
|
|
1195
|
+
let tmpDY = (pEvent.clientY - this._FrameStartPointerY) / tmpVS.Zoom;
|
|
1196
|
+
this._applyFrameEdit(
|
|
1197
|
+
{
|
|
1198
|
+
X: Math.round(this._FrameStart.X + tmpDX),
|
|
1199
|
+
Y: Math.round(this._FrameStart.Y + tmpDY),
|
|
1200
|
+
Width: this._FrameStart.Width,
|
|
1201
|
+
Height: this._FrameStart.Height
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
_applyFrameEdit(pBox)
|
|
1206
|
+
{
|
|
1207
|
+
let tmpFrame = this._FlowView._resolveFrame();
|
|
1208
|
+
if (!tmpFrame) return;
|
|
1209
|
+
tmpFrame.X = pBox.X;
|
|
1210
|
+
tmpFrame.Y = pBox.Y;
|
|
1211
|
+
tmpFrame.Width = pBox.Width;
|
|
1212
|
+
tmpFrame.Height = pBox.Height;
|
|
1213
|
+
this._FlowView._applyFrame();
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
_endFrameEdit(pEvent)
|
|
1217
|
+
{
|
|
1218
|
+
let tmpFrame = this._FlowView._resolveFrame();
|
|
1219
|
+
this._FlowView._applyFrame();
|
|
1220
|
+
if (typeof this._FlowView.marshalFromView === 'function') this._FlowView.marshalFromView();
|
|
1221
|
+
if (this._FlowView._EventHandlerProvider)
|
|
1222
|
+
{
|
|
1223
|
+
this._FlowView._EventHandlerProvider.fireEvent('onFrameChanged', tmpFrame);
|
|
1224
|
+
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
1225
|
+
}
|
|
1226
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1227
|
+
this._FrameDragEdge = null;
|
|
1228
|
+
this._FrameStart = null;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
/**
|
|
1232
|
+
* Pure box-resize math for the content frame: given the starting box, which edge is being
|
|
1233
|
+
* dragged ('n'|'e'|'s'|'w'), and the pointer delta in content units, return the new box,
|
|
1234
|
+
* clamped to a minimum size with the opposite edge held fixed. Unit tested without a DOM.
|
|
1235
|
+
* @param {Object} pStart - { X, Y, Width, Height }
|
|
1236
|
+
* @param {string} pEdge
|
|
1237
|
+
* @param {number} pDX
|
|
1238
|
+
* @param {number} pDY
|
|
1239
|
+
* @param {number} [pMinSize]
|
|
1240
|
+
* @returns {{X:number, Y:number, Width:number, Height:number}}
|
|
1241
|
+
*/
|
|
1242
|
+
static computeFrameResize(pStart, pEdge, pDX, pDY, pMinSize)
|
|
1243
|
+
{
|
|
1244
|
+
let tmpMin = (typeof pMinSize === 'number') ? pMinSize : 40;
|
|
1245
|
+
let tmpX = pStart.X;
|
|
1246
|
+
let tmpY = pStart.Y;
|
|
1247
|
+
let tmpW = pStart.Width;
|
|
1248
|
+
let tmpH = pStart.Height;
|
|
1249
|
+
switch (pEdge)
|
|
1250
|
+
{
|
|
1251
|
+
case 'n':
|
|
1252
|
+
{
|
|
1253
|
+
let tmpNewY = pStart.Y + pDY;
|
|
1254
|
+
let tmpNewH = pStart.Height - pDY;
|
|
1255
|
+
if (tmpNewH < tmpMin) { tmpNewY = pStart.Y + (pStart.Height - tmpMin); tmpNewH = tmpMin; }
|
|
1256
|
+
tmpY = Math.round(tmpNewY);
|
|
1257
|
+
tmpH = Math.round(tmpNewH);
|
|
1258
|
+
break;
|
|
1259
|
+
}
|
|
1260
|
+
case 's':
|
|
1261
|
+
tmpH = Math.round(Math.max(tmpMin, pStart.Height + pDY));
|
|
1262
|
+
break;
|
|
1263
|
+
case 'e':
|
|
1264
|
+
tmpW = Math.round(Math.max(tmpMin, pStart.Width + pDX));
|
|
1265
|
+
break;
|
|
1266
|
+
case 'w':
|
|
1267
|
+
{
|
|
1268
|
+
let tmpNewX = pStart.X + pDX;
|
|
1269
|
+
let tmpNewW = pStart.Width - pDX;
|
|
1270
|
+
if (tmpNewW < tmpMin) { tmpNewX = pStart.X + (pStart.Width - tmpMin); tmpNewW = tmpMin; }
|
|
1271
|
+
tmpX = Math.round(tmpNewX);
|
|
1272
|
+
tmpW = Math.round(tmpNewW);
|
|
1273
|
+
break;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return { X: tmpX, Y: tmpY, Width: tmpW, Height: tmpH };
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// ---- Node Rotation ----
|
|
1280
|
+
// Drag the grip on the arm above the selected node (rendered when EnableNodeRotation is on) to set
|
|
1281
|
+
// the node's Rotation in degrees: the card's top points toward the pointer. Hold Shift to snap to 15
|
|
1282
|
+
// degrees. The properties-panel rotation control still works; this is just a second, inline way.
|
|
1283
|
+
|
|
1284
|
+
_startNodeRotate(pEvent, pTarget)
|
|
1285
|
+
{
|
|
1286
|
+
if (!this._FlowView.options.EnableNodeRotation) return;
|
|
1287
|
+
if (this._isReadOnly()) return;
|
|
1288
|
+
|
|
1289
|
+
let tmpNodeHash = this._getNodeHash(pTarget);
|
|
1290
|
+
if (!tmpNodeHash) return;
|
|
1291
|
+
if (!this._FlowView.getNode(tmpNodeHash)) return;
|
|
1292
|
+
|
|
1293
|
+
this._setState(INTERACTION_STATES.ROTATING_NODE);
|
|
1294
|
+
this._RotateNodeHash = tmpNodeHash;
|
|
1295
|
+
if (pEvent.stopPropagation) pEvent.stopPropagation();
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
_onNodeRotate(pEvent)
|
|
1299
|
+
{
|
|
1300
|
+
if (!this._RotateNodeHash) return;
|
|
1301
|
+
|
|
1302
|
+
let tmpNode = this._FlowView.getNode(this._RotateNodeHash);
|
|
1303
|
+
if (!tmpNode) return;
|
|
1304
|
+
|
|
1305
|
+
let tmpCenterX = (tmpNode.X || 0) + (tmpNode.Width || 0) / 2;
|
|
1306
|
+
let tmpCenterY = (tmpNode.Y || 0) + (tmpNode.Height || 0) / 2;
|
|
1307
|
+
|
|
1308
|
+
// Pointer in content (SVG) space so pan/zoom do not skew the angle.
|
|
1309
|
+
let tmpPoint = this._FlowView.screenToSVGCoords(pEvent.clientX, pEvent.clientY);
|
|
1310
|
+
let tmpAngle = (Math.atan2(tmpPoint.y - tmpCenterY, tmpPoint.x - tmpCenterX) * 180 / Math.PI) + 90;
|
|
1311
|
+
|
|
1312
|
+
// Shift snaps to 15-degree increments.
|
|
1313
|
+
if (pEvent.shiftKey) { tmpAngle = Math.round(tmpAngle / 15) * 15; }
|
|
1314
|
+
|
|
1315
|
+
// Normalize to [0, 360).
|
|
1316
|
+
tmpAngle = ((Math.round(tmpAngle) % 360) + 360) % 360;
|
|
1317
|
+
tmpNode.Rotation = tmpAngle;
|
|
1318
|
+
|
|
1319
|
+
this._FlowView.renderFlow();
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
_endNodeRotate(pEvent)
|
|
1323
|
+
{
|
|
1324
|
+
this._FlowView.renderFlow();
|
|
1325
|
+
this._FlowView.marshalFromView();
|
|
1326
|
+
|
|
1327
|
+
let tmpNode = this._FlowView.getNode(this._RotateNodeHash);
|
|
1328
|
+
if (tmpNode && this._FlowView._EventHandlerProvider)
|
|
1329
|
+
{
|
|
1330
|
+
this._FlowView._EventHandlerProvider.fireEvent('onNodeRotated', tmpNode);
|
|
1331
|
+
this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView.flowData);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1335
|
+
this._RotateNodeHash = null;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
944
1338
|
// ---- Handle Dragging ----
|
|
945
1339
|
|
|
946
1340
|
_startHandleDrag(pEvent, pConnectionHash, pPanelHash, pHandleType, pIsTether)
|
|
947
1341
|
{
|
|
948
|
-
this.
|
|
1342
|
+
this._setState(INTERACTION_STATES.DRAGGING_HANDLE);
|
|
949
1343
|
this._DragHandleConnectionHash = pConnectionHash;
|
|
950
1344
|
this._DragHandlePanelHash = pPanelHash;
|
|
951
1345
|
this._DragHandleType = pHandleType;
|
|
952
1346
|
this._DragHandleIsTether = pIsTether;
|
|
953
1347
|
this._DragStartX = pEvent.clientX;
|
|
954
|
-
this._DragStartY = pEvent.clientY;
|
|
955
|
-
this._SVGElement.classList.add('panning');
|
|
956
|
-
}
|
|
1348
|
+
this._DragStartY = pEvent.clientY; }
|
|
957
1349
|
|
|
958
1350
|
_onHandleDrag(pEvent)
|
|
959
1351
|
{
|
|
@@ -981,8 +1373,6 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
981
1373
|
|
|
982
1374
|
_endHandleDrag(pEvent)
|
|
983
1375
|
{
|
|
984
|
-
this._SVGElement.classList.remove('panning');
|
|
985
|
-
|
|
986
1376
|
this._FlowView.renderFlow();
|
|
987
1377
|
this._FlowView.marshalFromView();
|
|
988
1378
|
|
|
@@ -1008,7 +1398,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1008
1398
|
}
|
|
1009
1399
|
}
|
|
1010
1400
|
|
|
1011
|
-
this.
|
|
1401
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1012
1402
|
this._DragHandleConnectionHash = null;
|
|
1013
1403
|
this._DragHandlePanelHash = null;
|
|
1014
1404
|
this._DragHandleType = null;
|
|
@@ -1169,12 +1559,10 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1169
1559
|
return;
|
|
1170
1560
|
}
|
|
1171
1561
|
|
|
1172
|
-
this.
|
|
1562
|
+
this._setState(INTERACTION_STATES.CONNECTING);
|
|
1173
1563
|
this._ConnectSourceNodeHash = tmpNodeHash;
|
|
1174
1564
|
this._ConnectSourcePortHash = tmpPortHash;
|
|
1175
1565
|
|
|
1176
|
-
this._SVGElement.classList.add('connecting');
|
|
1177
|
-
|
|
1178
1566
|
let tmpPortPos = this._FlowView.getPortPosition(tmpNodeHash, tmpPortHash);
|
|
1179
1567
|
if (tmpPortPos)
|
|
1180
1568
|
{
|
|
@@ -1209,8 +1597,6 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1209
1597
|
}
|
|
1210
1598
|
this._ConnectDragLine = null;
|
|
1211
1599
|
|
|
1212
|
-
this._SVGElement.classList.remove('connecting');
|
|
1213
|
-
|
|
1214
1600
|
let tmpTarget = document.elementFromPoint(pEvent.clientX, pEvent.clientY);
|
|
1215
1601
|
if (tmpTarget)
|
|
1216
1602
|
{
|
|
@@ -1230,7 +1616,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1230
1616
|
}
|
|
1231
1617
|
}
|
|
1232
1618
|
|
|
1233
|
-
this.
|
|
1619
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1234
1620
|
this._ConnectSourceNodeHash = null;
|
|
1235
1621
|
this._ConnectSourcePortHash = null;
|
|
1236
1622
|
}
|
|
@@ -1243,9 +1629,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1243
1629
|
}
|
|
1244
1630
|
this._ConnectDragLine = null;
|
|
1245
1631
|
|
|
1246
|
-
this.
|
|
1247
|
-
|
|
1248
|
-
this._State = INTERACTION_STATES.IDLE;
|
|
1632
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1249
1633
|
this._ConnectSourceNodeHash = null;
|
|
1250
1634
|
this._ConnectSourcePortHash = null;
|
|
1251
1635
|
}
|
|
@@ -1256,13 +1640,11 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1256
1640
|
{
|
|
1257
1641
|
this._FlowView.deselectAll();
|
|
1258
1642
|
|
|
1259
|
-
this.
|
|
1643
|
+
this._setState(INTERACTION_STATES.PANNING);
|
|
1260
1644
|
this._PanStartX = pEvent.clientX;
|
|
1261
1645
|
this._PanStartY = pEvent.clientY;
|
|
1262
1646
|
this._PanStartPanX = this._FlowView.viewState.PanX;
|
|
1263
1647
|
this._PanStartPanY = this._FlowView.viewState.PanY;
|
|
1264
|
-
|
|
1265
|
-
this._SVGElement.classList.add('panning');
|
|
1266
1648
|
}
|
|
1267
1649
|
|
|
1268
1650
|
_onPan(pEvent)
|
|
@@ -1277,9 +1659,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1277
1659
|
}
|
|
1278
1660
|
|
|
1279
1661
|
_endPanning(pEvent)
|
|
1280
|
-
{
|
|
1281
|
-
this._SVGElement.classList.remove('panning');
|
|
1282
|
-
this._State = INTERACTION_STATES.IDLE;
|
|
1662
|
+
{ this._setState(INTERACTION_STATES.IDLE);
|
|
1283
1663
|
}
|
|
1284
1664
|
|
|
1285
1665
|
// ---- Marquee selection (multi-select) ----
|
|
@@ -1295,7 +1675,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1295
1675
|
this._MarqueeStartY = tmpStart.y;
|
|
1296
1676
|
this._MarqueeCurrentX = tmpStart.x;
|
|
1297
1677
|
this._MarqueeCurrentY = tmpStart.y;
|
|
1298
|
-
this.
|
|
1678
|
+
this._setState(INTERACTION_STATES.MARQUEE);
|
|
1299
1679
|
|
|
1300
1680
|
let tmpRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
1301
1681
|
tmpRect.setAttribute('class', 'pict-flow-marquee');
|
|
@@ -1333,7 +1713,7 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
|
|
|
1333
1713
|
this._MarqueeElement.parentNode.removeChild(this._MarqueeElement);
|
|
1334
1714
|
}
|
|
1335
1715
|
this._MarqueeElement = null;
|
|
1336
|
-
this.
|
|
1716
|
+
this._setState(INTERACTION_STATES.IDLE);
|
|
1337
1717
|
|
|
1338
1718
|
// Too small to be a deliberate drag: treat as a background click and clear the selection.
|
|
1339
1719
|
if (tmpW < 4 && tmpH < 4)
|