pict-section-flow 1.4.0 → 2.0.1
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 +23 -3
- 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
|
@@ -32,6 +32,20 @@ class PictServiceFlowViewportManager extends libFableServiceProviderBase
|
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Pan the viewport by a delta in screen pixels (added to the current pan).
|
|
37
|
+
* Used by wheel-pan and any consumer that wants to nudge the canvas.
|
|
38
|
+
* @param {number} pDX
|
|
39
|
+
* @param {number} pDY
|
|
40
|
+
*/
|
|
41
|
+
panBy(pDX, pDY)
|
|
42
|
+
{
|
|
43
|
+
let tmpVS = this._FlowView._FlowData.ViewState;
|
|
44
|
+
tmpVS.PanX += pDX;
|
|
45
|
+
tmpVS.PanY += pDY;
|
|
46
|
+
this.updateViewportTransform();
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
/**
|
|
36
50
|
* Set zoom level
|
|
37
51
|
* @param {number} pZoom - The zoom level
|
|
@@ -95,6 +109,94 @@ class PictServiceFlowViewportManager extends libFableServiceProviderBase
|
|
|
95
109
|
this.updateViewportTransform();
|
|
96
110
|
}
|
|
97
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Fit the viewport to a content frame box (origin + size in content space),
|
|
114
|
+
* centering it with a little padding. Mirrors zoomToFit but for a fixed box
|
|
115
|
+
* rather than the node bounds.
|
|
116
|
+
* @param {Object} pFrame - { X, Y, Width, Height }
|
|
117
|
+
* @returns {boolean}
|
|
118
|
+
*/
|
|
119
|
+
fitToFrame(pFrame)
|
|
120
|
+
{
|
|
121
|
+
if (!pFrame || !pFrame.Width || !pFrame.Height) return false;
|
|
122
|
+
if (!this._FlowView._SVGElement) return false;
|
|
123
|
+
|
|
124
|
+
let tmpPadding = 20;
|
|
125
|
+
let tmpFrameWidth = pFrame.Width + tmpPadding * 2;
|
|
126
|
+
let tmpFrameHeight = pFrame.Height + tmpPadding * 2;
|
|
127
|
+
|
|
128
|
+
let tmpSVGRect = this._FlowView._SVGElement.getBoundingClientRect();
|
|
129
|
+
let tmpScaleX = tmpSVGRect.width / tmpFrameWidth;
|
|
130
|
+
let tmpScaleY = tmpSVGRect.height / tmpFrameHeight;
|
|
131
|
+
let tmpZoom = Math.min(tmpScaleX, tmpScaleY);
|
|
132
|
+
tmpZoom = Math.max(this._FlowView.options.MinZoom, Math.min(this._FlowView.options.MaxZoom, tmpZoom));
|
|
133
|
+
|
|
134
|
+
let tmpCenterX = (pFrame.X || 0) + pFrame.Width / 2;
|
|
135
|
+
let tmpCenterY = (pFrame.Y || 0) + pFrame.Height / 2;
|
|
136
|
+
|
|
137
|
+
this._FlowView._FlowData.ViewState.Zoom = tmpZoom;
|
|
138
|
+
this._FlowView._FlowData.ViewState.PanX = (tmpSVGRect.width / 2) - (tmpCenterX * tmpZoom);
|
|
139
|
+
this._FlowView._FlowData.ViewState.PanY = (tmpSVGRect.height / 2) - (tmpCenterY * tmpZoom);
|
|
140
|
+
|
|
141
|
+
this.updateViewportTransform();
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Fit the frame's WIDTH to the container width (vs fitToFrame, which contains the whole
|
|
147
|
+
* frame and centers it), anchoring the frame's top-left at the container's top-left plus
|
|
148
|
+
* an optional top margin. Content outside the frame bleeds past the edges on purpose;
|
|
149
|
+
* vertical overflow is the host's call (a jumbotron clips to the frame height, a
|
|
150
|
+
* fullscreen / background view lets the user scroll down).
|
|
151
|
+
* @param {Object} pFrame - { X, Y, Width }
|
|
152
|
+
* @param {Object} [pOptions] - { TopMargin }
|
|
153
|
+
* @returns {boolean}
|
|
154
|
+
*/
|
|
155
|
+
fitToFrameWidth(pFrame, pOptions)
|
|
156
|
+
{
|
|
157
|
+
if (!pFrame || !pFrame.Width) return false;
|
|
158
|
+
if (!this._FlowView._SVGElement) return false;
|
|
159
|
+
|
|
160
|
+
let tmpRect = this._FlowView._SVGElement.getBoundingClientRect();
|
|
161
|
+
let tmpResult = PictServiceFlowViewportManager.computeFitToWidth(pFrame, tmpRect.width,
|
|
162
|
+
{
|
|
163
|
+
TopMargin: (pOptions && pOptions.TopMargin) || 0,
|
|
164
|
+
MinZoom: this._FlowView.options.MinZoom,
|
|
165
|
+
MaxZoom: this._FlowView.options.MaxZoom
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
this._FlowView._FlowData.ViewState.Zoom = tmpResult.Zoom;
|
|
169
|
+
this._FlowView._FlowData.ViewState.PanX = tmpResult.PanX;
|
|
170
|
+
this._FlowView._FlowData.ViewState.PanY = tmpResult.PanY;
|
|
171
|
+
|
|
172
|
+
this.updateViewportTransform();
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Pure fit-to-width math: zoom so the frame's width equals the container width (clamped to
|
|
178
|
+
* the view's zoom bounds), and pan so the frame's top-left sits at (0, TopMargin). No DOM,
|
|
179
|
+
* so it is unit tested directly.
|
|
180
|
+
* @param {Object} pFrame - { X, Y, Width }
|
|
181
|
+
* @param {number} pContainerWidth
|
|
182
|
+
* @param {Object} [pOptions] - { TopMargin, MinZoom, MaxZoom }
|
|
183
|
+
* @returns {{Zoom:number, PanX:number, PanY:number}}
|
|
184
|
+
*/
|
|
185
|
+
static computeFitToWidth(pFrame, pContainerWidth, pOptions)
|
|
186
|
+
{
|
|
187
|
+
let tmpOptions = pOptions || {};
|
|
188
|
+
let tmpZoom = (pFrame && pFrame.Width > 0 && pContainerWidth > 0) ? (pContainerWidth / pFrame.Width) : 1;
|
|
189
|
+
let tmpMin = (typeof tmpOptions.MinZoom === 'number') ? tmpOptions.MinZoom : 0.05;
|
|
190
|
+
let tmpMax = (typeof tmpOptions.MaxZoom === 'number') ? tmpOptions.MaxZoom : 8;
|
|
191
|
+
tmpZoom = Math.max(tmpMin, Math.min(tmpMax, tmpZoom));
|
|
192
|
+
let tmpTopMargin = tmpOptions.TopMargin || 0;
|
|
193
|
+
return {
|
|
194
|
+
Zoom: tmpZoom,
|
|
195
|
+
PanX: -(((pFrame && pFrame.X) || 0) * tmpZoom),
|
|
196
|
+
PanY: tmpTopMargin - (((pFrame && pFrame.Y) || 0) * tmpZoom)
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
98
200
|
/**
|
|
99
201
|
* Convert screen coordinates to SVG viewport coordinates
|
|
100
202
|
* @param {number} pScreenX
|
|
@@ -81,9 +81,10 @@ const _DefaultConfiguration =
|
|
|
81
81
|
Hash: 'Flow-FloatingToolbar-Extra-Button',
|
|
82
82
|
// Icon-only host button (the floating toolbar is compact). Icon span
|
|
83
83
|
// is filled post-render by _populateIcons (keyed by Hash).
|
|
84
|
-
Template: /*html*/`<button class="pict-flow-floating-btn" title="{~D:Record.Tooltip~}" data-flow-action="extra" data-extra-hash="{~D:Record.Hash~}"
|
|
84
|
+
Template: /*html*/`<button class="pict-flow-floating-btn{~D:Record.ToggleClass~}{~D:Record.ActiveClass~}" title="{~D:Record.Tooltip~}" data-flow-action="extra" data-extra-hash="{~D:Record.Hash~}"
|
|
85
85
|
onclick="_Pict.views['{~D:Record.FlowViewIdentifier~}']._ToolbarView._FloatingToolbarView._handleExtraClick('{~D:Record.Hash~}', this)">
|
|
86
86
|
<span id="Flow-FloatingExtraIcon-{~D:Record.Hash~}-{~D:Record.FlowViewIdentifier~}"></span>
|
|
87
|
+
<span class="pict-flow-toolbar-btn-led" aria-hidden="true"></span>
|
|
87
88
|
</button>`
|
|
88
89
|
}
|
|
89
90
|
],
|
|
@@ -132,6 +133,9 @@ class PictViewFlowFloatingToolbar extends libPictView
|
|
|
132
133
|
for (let i = 0; i < tmpExtraButtons.length; i++)
|
|
133
134
|
{
|
|
134
135
|
tmpExtraButtons[i].FlowViewIdentifier = this.options.FlowViewIdentifier;
|
|
136
|
+
// Mirror the docked toolbar so toggle buttons show the same status LED here.
|
|
137
|
+
tmpExtraButtons[i].ToggleClass = tmpExtraButtons[i].Toggle ? ' pict-flow-toolbar-btn-toggle' : '';
|
|
138
|
+
tmpExtraButtons[i].ActiveClass = tmpExtraButtons[i].Active ? ' pict-flow-toolbar-btn-active' : '';
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
return super.render(pRenderableHash, pRenderDestinationAddress, this.options);
|
|
@@ -346,6 +346,35 @@ class PictViewFlowNode extends libPictView
|
|
|
346
346
|
tmpGroup.appendChild(tmpHandle);
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
// Rotate handle: a grip on a short arm above the node, shown when this node is selected, the
|
|
350
|
+
// flow allows rotation, and we are not read-only. Its data-element-type routes pointer-down to
|
|
351
|
+
// the InteractionManager's node-rotate path. Lives in node-local space, so it orbits with the card.
|
|
352
|
+
if (pIsSelected && this._FlowView.options && this._FlowView.options.EnableNodeRotation
|
|
353
|
+
&& !(typeof this._FlowView.isReadOnly === 'function' && this._FlowView.isReadOnly()))
|
|
354
|
+
{
|
|
355
|
+
let tmpArmLength = 22;
|
|
356
|
+
let tmpRotateCenterX = tmpWidth / 2;
|
|
357
|
+
|
|
358
|
+
let tmpArm = this._FlowView._SVGHelperProvider.createSVGElement('line');
|
|
359
|
+
tmpArm.setAttribute('class', 'pict-flow-node-rotate-arm');
|
|
360
|
+
tmpArm.setAttribute('x1', String(tmpRotateCenterX));
|
|
361
|
+
tmpArm.setAttribute('y1', '0');
|
|
362
|
+
tmpArm.setAttribute('x2', String(tmpRotateCenterX));
|
|
363
|
+
tmpArm.setAttribute('y2', String(-tmpArmLength));
|
|
364
|
+
tmpArm.setAttribute('data-node-hash', pNodeData.Hash);
|
|
365
|
+
tmpArm.setAttribute('data-element-type', 'node-rotate');
|
|
366
|
+
tmpGroup.appendChild(tmpArm);
|
|
367
|
+
|
|
368
|
+
let tmpGrip = this._FlowView._SVGHelperProvider.createSVGElement('circle');
|
|
369
|
+
tmpGrip.setAttribute('class', 'pict-flow-node-rotate-handle');
|
|
370
|
+
tmpGrip.setAttribute('cx', String(tmpRotateCenterX));
|
|
371
|
+
tmpGrip.setAttribute('cy', String(-tmpArmLength - 5));
|
|
372
|
+
tmpGrip.setAttribute('r', '6');
|
|
373
|
+
tmpGrip.setAttribute('data-node-hash', pNodeData.Hash);
|
|
374
|
+
tmpGrip.setAttribute('data-element-type', 'node-rotate');
|
|
375
|
+
tmpGroup.appendChild(tmpGrip);
|
|
376
|
+
}
|
|
377
|
+
|
|
349
378
|
pNodesLayer.appendChild(tmpGroup);
|
|
350
379
|
}
|
|
351
380
|
|
|
@@ -117,10 +117,11 @@ const _DefaultConfiguration =
|
|
|
117
117
|
// _populateToolbarIcons (keyed by Hash), matching how the built-in
|
|
118
118
|
// button icons are injected. FlowViewIdentifier + ActiveClass are
|
|
119
119
|
// stamped onto each row in render().
|
|
120
|
-
Template: /*html*/`<button class="pict-flow-toolbar-btn{~D:Record.ActiveClass~}" id="Flow-Toolbar-Extra-{~D:Record.Hash~}-{~D:Record.FlowViewIdentifier~}" title="{~D:Record.Tooltip~}" data-flow-action="extra" data-extra-hash="{~D:Record.Hash~}"
|
|
120
|
+
Template: /*html*/`<button class="pict-flow-toolbar-btn{~D:Record.ToggleClass~}{~D:Record.ActiveClass~}" id="Flow-Toolbar-Extra-{~D:Record.Hash~}-{~D:Record.FlowViewIdentifier~}" title="{~D:Record.Tooltip~}" data-flow-action="extra" data-extra-hash="{~D:Record.Hash~}"
|
|
121
121
|
onclick="_Pict.views['{~D:Record.FlowViewIdentifier~}']._ToolbarView._handleExtraAction('{~D:Record.Hash~}', this)">
|
|
122
122
|
<span class="pict-flow-toolbar-btn-icon" id="Flow-Toolbar-ExtraIcon-{~D:Record.Hash~}-{~D:Record.FlowViewIdentifier~}"></span>
|
|
123
123
|
<span class="pict-flow-toolbar-btn-text">{~D:Record.Label~}</span>
|
|
124
|
+
<span class="pict-flow-toolbar-btn-led" aria-hidden="true"></span>
|
|
124
125
|
</button>`
|
|
125
126
|
},
|
|
126
127
|
{
|
|
@@ -253,6 +254,9 @@ class PictViewFlowToolbar extends libPictView
|
|
|
253
254
|
{
|
|
254
255
|
tmpExtraButtons[i].FlowViewIdentifier = this.options.FlowViewIdentifier;
|
|
255
256
|
tmpExtraButtons[i].ActiveClass = tmpExtraButtons[i].Active ? ' pict-flow-toolbar-btn-active' : '';
|
|
257
|
+
// Toggle buttons (stateful on/off, e.g. a pan or connect toggle) get a status LED that the
|
|
258
|
+
// ActiveClass fills; plain action buttons (Toggle falsy) render no LED.
|
|
259
|
+
tmpExtraButtons[i].ToggleClass = tmpExtraButtons[i].Toggle ? ' pict-flow-toolbar-btn-toggle' : '';
|
|
256
260
|
// A label-less (icon-only) button renders an empty text span; CSS (:empty) collapses it.
|
|
257
261
|
if (typeof tmpExtraButtons[i].Label !== 'string') { tmpExtraButtons[i].Label = ''; }
|
|
258
262
|
}
|
|
@@ -1602,7 +1606,7 @@ class PictViewFlowToolbar extends libPictView
|
|
|
1602
1606
|
let tmpNoiseEnabled = !!(tmpActiveRenderer && tmpActiveRenderer.NoiseConfig && tmpActiveRenderer.NoiseConfig.Enabled);
|
|
1603
1607
|
let tmpNoiseDisplay = tmpNoiseEnabled ? '' : 'display:none;';
|
|
1604
1608
|
|
|
1605
|
-
|
|
1609
|
+
let tmpHTML =
|
|
1606
1610
|
'<div class="pict-flow-popup-settings-section">'
|
|
1607
1611
|
+ '<label class="pict-flow-popup-settings-label">Theme</label>'
|
|
1608
1612
|
+ '<select class="pict-flow-popup-settings-select"'
|
|
@@ -1621,7 +1625,50 @@ class PictViewFlowToolbar extends libPictView
|
|
|
1621
1625
|
+ ' oninput="_Pict.views[\'' + tmpFlowViewIdentifier + '\']._ToolbarView._handleNoiseSliderInput(this)" />'
|
|
1622
1626
|
+ '<span class="pict-flow-popup-settings-slider-value">' + tmpNoiseLevel + '%</span>'
|
|
1623
1627
|
+ '</div>'
|
|
1624
|
-
+ '</div>'
|
|
1628
|
+
+ '</div>';
|
|
1629
|
+
|
|
1630
|
+
tmpHTML += this._buildHostSettingsSections();
|
|
1631
|
+
|
|
1632
|
+
this.pict.ContentAssignment.assignContent(pContainer, tmpHTML);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Host-contributed settings sections. A consumer adds entries to the flow view's
|
|
1637
|
+
* `SettingsSections` option so its own controls (e.g. a whiteboard's background
|
|
1638
|
+
* picker) live in the gear popup instead of a separate panel. Each entry is
|
|
1639
|
+
* `{ Label?, HTML? , Build?(flowView) }`; Build is evaluated at open time so a
|
|
1640
|
+
* section can reflect live state. Returns concatenated section markup ('' when none).
|
|
1641
|
+
* @returns {string}
|
|
1642
|
+
*/
|
|
1643
|
+
_buildHostSettingsSections()
|
|
1644
|
+
{
|
|
1645
|
+
let tmpSections = (this._FlowView && this._FlowView.options && Array.isArray(this._FlowView.options.SettingsSections))
|
|
1646
|
+
? this._FlowView.options.SettingsSections
|
|
1647
|
+
: [];
|
|
1648
|
+
let tmpOut = '';
|
|
1649
|
+
for (let i = 0; i < tmpSections.length; i++)
|
|
1650
|
+
{
|
|
1651
|
+
let tmpSection = tmpSections[i];
|
|
1652
|
+
let tmpSectionHTML = '';
|
|
1653
|
+
if (typeof tmpSection.Build === 'function')
|
|
1654
|
+
{
|
|
1655
|
+
tmpSectionHTML = tmpSection.Build(this._FlowView) || '';
|
|
1656
|
+
}
|
|
1657
|
+
else if (typeof tmpSection.HTML === 'string')
|
|
1658
|
+
{
|
|
1659
|
+
tmpSectionHTML = tmpSection.HTML;
|
|
1660
|
+
}
|
|
1661
|
+
if (!tmpSectionHTML)
|
|
1662
|
+
{
|
|
1663
|
+
continue;
|
|
1664
|
+
}
|
|
1665
|
+
tmpOut += '<div class="pict-flow-popup-divider"></div>'
|
|
1666
|
+
+ '<div class="pict-flow-popup-settings-section">'
|
|
1667
|
+
+ (tmpSection.Label ? '<label class="pict-flow-popup-settings-label">' + tmpSection.Label + '</label>' : '')
|
|
1668
|
+
+ tmpSectionHTML
|
|
1669
|
+
+ '</div>';
|
|
1670
|
+
}
|
|
1671
|
+
return tmpOut;
|
|
1625
1672
|
}
|
|
1626
1673
|
|
|
1627
1674
|
/**
|