pict-section-flow 1.0.0 → 1.1.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.
Files changed (71) hide show
  1. package/README.md +44 -13
  2. package/docs/Architecture.md +8 -148
  3. package/docs/Data_Model.md +2 -11
  4. package/docs/README.md +8 -38
  5. package/docs/Theme_Integration.md +13 -13
  6. package/docs/_cover.md +7 -1
  7. package/docs/_playground.json +24 -0
  8. package/docs/_sidebar.md +4 -0
  9. package/docs/_topbar.md +1 -1
  10. package/docs/_version.json +3 -3
  11. package/docs/card-help/FREAD.md +1 -1
  12. package/docs/diagrams/architecture-at-a-glance.excalidraw +4270 -0
  13. package/docs/diagrams/architecture-at-a-glance.mmd +30 -0
  14. package/docs/diagrams/architecture-at-a-glance.svg +2 -0
  15. package/docs/diagrams/data-flow.excalidraw +1451 -0
  16. package/docs/diagrams/data-flow.mmd +17 -0
  17. package/docs/diagrams/data-flow.svg +2 -0
  18. package/docs/diagrams/high-level-design.excalidraw +5767 -0
  19. package/docs/diagrams/high-level-design.mmd +86 -0
  20. package/docs/diagrams/high-level-design.svg +2 -0
  21. package/docs/diagrams/relationships.excalidraw +3852 -0
  22. package/docs/diagrams/relationships.mmd +9 -0
  23. package/docs/diagrams/relationships.svg +2 -0
  24. package/docs/diagrams/service-initialization-sequence.excalidraw +1466 -0
  25. package/docs/diagrams/service-initialization-sequence.mmd +19 -0
  26. package/docs/diagrams/service-initialization-sequence.svg +2 -0
  27. package/docs/diagrams/svg-layer-structure.excalidraw +1060 -0
  28. package/docs/diagrams/svg-layer-structure.mmd +18 -0
  29. package/docs/diagrams/svg-layer-structure.svg +2 -0
  30. package/docs/examples/README.md +9 -0
  31. package/docs/examples/simple_cards/README.md +677 -0
  32. package/docs/examples/simple_cards/css/flowexample.css +65 -0
  33. package/docs/examples/simple_cards/index.html +32 -0
  34. package/docs/examples/simple_cards/js/pict.min.js +12 -0
  35. package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +1 -0
  36. package/docs/index.html +6 -7
  37. package/docs/playground/app.json +6 -0
  38. package/docs/playground/appdata.json +85 -0
  39. package/docs/playground/application.js +23 -0
  40. package/docs/playground/pict.json +17 -0
  41. package/docs/playground/runtime/pict-application.min.js +2 -0
  42. package/docs/playground/runtime/pict-section-flow.min.js +2 -0
  43. package/docs/playground/runtime/pict-section-modal.min.js +2 -0
  44. package/docs/playground/runtime/pict.min.js +12 -0
  45. package/docs/retold-catalog.json +241 -166
  46. package/docs/retold-keyword-index.json +19312 -7226
  47. package/example_applications/simple_cards/package.json +9 -1
  48. package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +2 -2
  49. package/package.json +5 -5
  50. package/source/PictFlowCard.js +2 -2
  51. package/source/providers/PictProvider-Flow-CSS.js +38 -12
  52. package/source/providers/PictProvider-Flow-ConnectorShapes.js +8 -8
  53. package/source/providers/PictProvider-Flow-Icons.js +33 -33
  54. package/source/providers/PictProvider-Flow-NodeTypes.js +9 -9
  55. package/source/providers/PictProvider-Flow-PanelChrome.js +2 -1
  56. package/source/providers/PictProvider-Flow-Renderer.js +516 -0
  57. package/source/providers/PictProvider-Flow-StylePresets.js +259 -0
  58. package/source/providers/PictProvider-Flow-Theme.js +97 -669
  59. package/source/services/PictService-Flow-ConnectionRenderer.js +6 -6
  60. package/source/services/PictService-Flow-DataManager.js +6 -0
  61. package/source/services/PictService-Flow-InteractionManager.js +10 -1
  62. package/source/services/PictService-Flow-PanelManager.js +106 -2
  63. package/source/services/PictService-Flow-PortRenderer.js +6 -6
  64. package/source/views/PictView-Flow-Node.js +1 -1
  65. package/source/views/PictView-Flow-PropertiesPanel.js +71 -4
  66. package/source/views/PictView-Flow-Toolbar.js +24 -16
  67. package/source/views/PictView-Flow.js +225 -47
  68. package/test/PanelManager_tests.js +172 -0
  69. package/test/Renderer_tests.js +133 -0
  70. package/test/StylePresets_tests.js +153 -0
  71. package/docs/css/docuserve.css +0 -327
@@ -15,13 +15,13 @@ const _CHIP_PER_CHAR_PX = 5;
15
15
  // badge borders so the hint bezier matches its port's affinity color.
16
16
  const PORT_TYPE_COLORS =
17
17
  {
18
- 'event-in': '#3498db',
19
- 'event-out': '#2ecc71',
20
- 'setting': '#e67e22',
21
- 'value': '#f1c40f',
22
- 'error': '#e74c3c'
18
+ 'event-in': 'var(--theme-color-status-info, #3498db)',
19
+ 'event-out': 'var(--theme-color-status-success, #2ecc71)',
20
+ 'setting': 'var(--theme-color-status-warning, #e67e22)',
21
+ 'value': 'var(--theme-color-status-warning, #f1c40f)',
22
+ 'error': 'var(--theme-color-status-error, #e74c3c)'
23
23
  };
24
- const PORT_TYPE_DEFAULT_COLOR = '#95a5a6';
24
+ const PORT_TYPE_DEFAULT_COLOR = 'var(--theme-color-border-default, #95a5a6)';
25
25
 
26
26
  class PictServiceFlowConnectionRenderer extends libFableServiceProviderBase
27
27
  {
@@ -328,6 +328,12 @@ class PictServiceFlowDataManager extends libFableServiceProviderBase
328
328
 
329
329
  let tmpRemovedConnection = this._FlowView._FlowData.Connections.splice(tmpConnectionIndex, 1)[0];
330
330
 
331
+ // Close any properties panel open for this connection.
332
+ if (typeof this._FlowView.closePanelForConnection === 'function')
333
+ {
334
+ this._FlowView.closePanelForConnection(pConnectionHash);
335
+ }
336
+
331
337
  if (this._FlowView._FlowData.ViewState.SelectedConnectionHash === pConnectionHash)
332
338
  {
333
339
  this._FlowView._FlowData.ViewState.SelectedConnectionHash = null;
@@ -322,7 +322,16 @@ class PictServiceFlowInteractionManager extends libFableServiceProviderBase
322
322
  {
323
323
  this._LastConnectionClickTime = 0;
324
324
  this._LastConnectionClickHash = null;
325
- this._addBezierHandle(tmpTarget, pEvent);
325
+ // When the host configured a connection properties panel, double-click opens it;
326
+ // otherwise keep the default behavior of adding a bezier handle.
327
+ if (this._FlowView.options.ConnectionPropertiesPanel && tmpConnectionHash)
328
+ {
329
+ this._FlowView.toggleConnectionPanel(tmpConnectionHash);
330
+ }
331
+ else
332
+ {
333
+ this._addBezierHandle(tmpTarget, pEvent);
334
+ }
326
335
  }
327
336
  else
328
337
  {
@@ -152,6 +152,98 @@ class PictServiceFlowPanelManager extends libFableServiceProviderBase
152
152
  return this.openPanel(pNodeHash);
153
153
  }
154
154
 
155
+ /**
156
+ * Open a properties panel for a connection (edge). The panel config comes from the FlowView's
157
+ * ConnectionPropertiesPanel option (connections are not typed, so one config serves them all);
158
+ * the panel is placed near the connection's midpoint and tethers to it. Returns false when no
159
+ * ConnectionPropertiesPanel is configured, so a host that has not opted in keeps the default
160
+ * edge behavior (double-click adds a bezier handle).
161
+ * @param {string} pConnectionHash
162
+ * @returns {Object|false} The panel data, or false
163
+ */
164
+ openConnectionPanel(pConnectionHash)
165
+ {
166
+ let tmpConnection = this._FlowView.getConnection(pConnectionHash);
167
+ if (!tmpConnection) return false;
168
+
169
+ let tmpPanelConfig = this._FlowView.options.ConnectionPropertiesPanel;
170
+ if (!tmpPanelConfig) return false;
171
+
172
+ let tmpExisting = this._FlowView._FlowData.OpenPanels.find((pPanel) => pPanel.ConnectionHash === pConnectionHash);
173
+ if (tmpExisting) return tmpExisting;
174
+
175
+ let tmpMidpoint = this._FlowView.getConnectionMidpoint(pConnectionHash) || { x: 0, y: 0 };
176
+ let tmpWidth = tmpPanelConfig.DefaultWidth || 300;
177
+ let tmpHeight = tmpPanelConfig.DefaultHeight || 200;
178
+
179
+ let tmpPanelData =
180
+ {
181
+ Hash: `panel-${this.fable.getUUID()}`,
182
+ ConnectionHash: pConnectionHash,
183
+ NodeHash: null,
184
+ PanelType: tmpPanelConfig.PanelType || 'Base',
185
+ Title: tmpPanelConfig.Title || 'Connection',
186
+ X: tmpMidpoint.x + 40,
187
+ Y: tmpMidpoint.y + 20,
188
+ Width: tmpWidth,
189
+ Height: tmpHeight
190
+ };
191
+
192
+ this._FlowView._FlowData.OpenPanels.push(tmpPanelData);
193
+ this._FlowView.renderFlow();
194
+ this._FlowView.marshalFromView();
195
+
196
+ if (this._FlowView._EventHandlerProvider)
197
+ {
198
+ this._FlowView._EventHandlerProvider.fireEvent('onPanelOpened', tmpPanelData);
199
+ this._FlowView._EventHandlerProvider.fireEvent('onFlowChanged', this._FlowView._FlowData);
200
+ }
201
+
202
+ return tmpPanelData;
203
+ }
204
+
205
+ /**
206
+ * Toggle a properties panel for a connection (open if closed, close if open).
207
+ * @param {string} pConnectionHash
208
+ * @returns {Object|false}
209
+ */
210
+ toggleConnectionPanel(pConnectionHash)
211
+ {
212
+ let tmpExisting = this._FlowView._FlowData.OpenPanels.find((pPanel) => pPanel.ConnectionHash === pConnectionHash);
213
+ if (tmpExisting)
214
+ {
215
+ this.closePanel(tmpExisting.Hash);
216
+ return false;
217
+ }
218
+ return this.openConnectionPanel(pConnectionHash);
219
+ }
220
+
221
+ /**
222
+ * Close all panels for a given connection.
223
+ * @param {string} pConnectionHash
224
+ * @returns {boolean}
225
+ */
226
+ closePanelForConnection(pConnectionHash)
227
+ {
228
+ let tmpPanelsToClose = this._FlowView._FlowData.OpenPanels.filter((pPanel) => pPanel.ConnectionHash === pConnectionHash);
229
+ if (tmpPanelsToClose.length === 0) return false;
230
+
231
+ for (let i = 0; i < tmpPanelsToClose.length; i++)
232
+ {
233
+ let tmpIndex = this._FlowView._FlowData.OpenPanels.indexOf(tmpPanelsToClose[i]);
234
+ if (tmpIndex >= 0)
235
+ {
236
+ this._FlowView._FlowData.OpenPanels.splice(tmpIndex, 1);
237
+ }
238
+ if (this._FlowView._PropertiesPanelView)
239
+ {
240
+ this._FlowView._PropertiesPanelView.destroyPanel(tmpPanelsToClose[i].Hash);
241
+ }
242
+ }
243
+
244
+ return true;
245
+ }
246
+
155
247
  /**
156
248
  * Update a panel's position (for drag).
157
249
  * @param {string} pPanelHash
@@ -180,8 +272,20 @@ class PictServiceFlowPanelManager extends libFableServiceProviderBase
180
272
  }
181
273
  }
182
274
 
183
- // Update the tether for this panel
184
- this._FlowView._renderTethersForNode(tmpPanel.NodeHash);
275
+ // Update the tether for this panel. A node panel refreshes just its node's tethers; a
276
+ // connection panel has no node, so reconcile the panels layer (redraws all tethers, which
277
+ // is where the connection-midpoint tether is recomputed).
278
+ if (tmpPanel.ConnectionHash)
279
+ {
280
+ if (this._FlowView._PropertiesPanelView && this._FlowView._PanelsLayer && this._FlowView._TethersLayer)
281
+ {
282
+ this._FlowView._PropertiesPanelView.renderPanels(this._FlowView._FlowData.OpenPanels, this._FlowView._PanelsLayer, this._FlowView._TethersLayer, this._FlowView._FlowData.ViewState.SelectedTetherHash);
283
+ }
284
+ }
285
+ else
286
+ {
287
+ this._FlowView._renderTethersForNode(tmpPanel.NodeHash);
288
+ }
185
289
  }
186
290
  }
187
291
 
@@ -88,13 +88,13 @@ class PictServiceFlowPortRenderer extends libFableServiceProviderBase
88
88
  {
89
89
  let tmpPortTypeColorMap =
90
90
  {
91
- 'event-in': '#3498db',
92
- 'event-out': '#2ecc71',
93
- 'setting': '#e67e22',
94
- 'value': '#f1c40f',
95
- 'error': '#e74c3c'
91
+ 'event-in': 'var(--theme-color-status-info, #3498db)',
92
+ 'event-out': 'var(--theme-color-status-success, #2ecc71)',
93
+ 'setting': 'var(--theme-color-status-warning, #e67e22)',
94
+ 'value': 'var(--theme-color-status-warning, #f1c40f)',
95
+ 'error': 'var(--theme-color-status-error, #e74c3c)'
96
96
  };
97
- let tmpBorderColor = tmpPort.PortType ? (tmpPortTypeColorMap[tmpPort.PortType] || '#95a5a6') : '#95a5a6';
97
+ let tmpBorderColor = tmpPort.PortType ? (tmpPortTypeColorMap[tmpPort.PortType] || 'var(--theme-color-border-default, #95a5a6)') : 'var(--theme-color-border-default, #95a5a6)';
98
98
 
99
99
  let tmpBadgeHeight = 12;
100
100
  let tmpBadgePadH = 5;
@@ -239,7 +239,7 @@ class PictViewFlowNode extends libPictView
239
239
  tmpCodeText.setAttribute('class', 'pict-flow-node-card-code');
240
240
  tmpCodeText.setAttribute('font-size', '10');
241
241
  tmpCodeText.setAttribute('font-family', 'monospace');
242
- tmpCodeText.setAttribute('fill', '#7f8c8d');
242
+ tmpCodeText.setAttribute('fill', 'var(--theme-color-text-secondary, #7f8c8d)');
243
243
  tmpCodeText.setAttribute('text-anchor', 'middle');
244
244
  tmpCodeText.setAttribute('dominant-baseline', 'central');
245
245
  tmpCodeText.setAttribute('pointer-events', 'none');
@@ -242,6 +242,13 @@ class PictViewFlowPropertiesPanel extends libPictView
242
242
  */
243
243
  _renderPanelContent(pPanelData, pBodyContainer)
244
244
  {
245
+ // Connection (edge) panels resolve their config and data differently from node panels.
246
+ if (pPanelData.ConnectionHash)
247
+ {
248
+ this._renderConnectionPanelContent(pPanelData, pBodyContainer);
249
+ return;
250
+ }
251
+
245
252
  let tmpNodeData = this._FlowView.getNode(pPanelData.NodeHash);
246
253
  if (!tmpNodeData) return;
247
254
 
@@ -298,6 +305,54 @@ class PictViewFlowPropertiesPanel extends libPictView
298
305
  this._renderPortSummary(pBodyContainer, tmpNodeTypeConfig);
299
306
  }
300
307
 
308
+ /**
309
+ * Render the content of a connection (edge) panel. The config is the FlowView's single
310
+ * ConnectionPropertiesPanel (connections are not typed); the panel-type instance renders
311
+ * against the connection object, so a Form panel edits Connection.Data.* and a Template panel
312
+ * renders against the connection.
313
+ *
314
+ * @param {Object} pPanelData
315
+ * @param {HTMLDivElement} pBodyContainer
316
+ */
317
+ _renderConnectionPanelContent(pPanelData, pBodyContainer)
318
+ {
319
+ let tmpConnectionData = this._FlowView.getConnection(pPanelData.ConnectionHash);
320
+ if (!tmpConnectionData) return;
321
+
322
+ let tmpPanelConfig = this._FlowView.options.ConnectionPropertiesPanel;
323
+ if (!tmpPanelConfig)
324
+ {
325
+ pBodyContainer.innerHTML = '<em>No connection properties panel configured.</em>';
326
+ return;
327
+ }
328
+
329
+ let tmpPanelType = tmpPanelConfig.PanelType || 'Base';
330
+ let tmpServiceName = `PictFlowCardPropertiesPanel-${tmpPanelType}`;
331
+ let tmpInstance = this._PanelInstances[pPanelData.Hash];
332
+
333
+ if (!tmpInstance)
334
+ {
335
+ if (this.fable.servicesMap.hasOwnProperty(tmpServiceName))
336
+ {
337
+ tmpInstance = this.fable.instantiateServiceProviderWithoutRegistration(tmpServiceName, tmpPanelConfig);
338
+ }
339
+ else if (this.fable.servicesMap.hasOwnProperty('PictFlowCardPropertiesPanel'))
340
+ {
341
+ tmpInstance = this.fable.instantiateServiceProviderWithoutRegistration('PictFlowCardPropertiesPanel', tmpPanelConfig);
342
+ }
343
+ if (tmpInstance)
344
+ {
345
+ tmpInstance._FlowView = this._FlowView;
346
+ this._PanelInstances[pPanelData.Hash] = tmpInstance;
347
+ }
348
+ }
349
+
350
+ if (tmpInstance)
351
+ {
352
+ tmpInstance.render(pBodyContainer, tmpConnectionData);
353
+ }
354
+ }
355
+
301
356
  /**
302
357
  * Render an auto-generated info panel for nodes without a configured PropertiesPanel.
303
358
  * Shows the node type, description, and a summary of input/output ports with
@@ -547,7 +602,7 @@ class PictViewFlowPropertiesPanel extends libPictView
547
602
 
548
603
  // Resolve default colors from the node type config or CSS token defaults
549
604
  let tmpNodeTypeConfig = this._FlowView._NodeTypeProvider.getNodeType(tmpNodeData.Type);
550
- let tmpDefaultTitleBarColor = '#2c3e50';
605
+ let tmpDefaultTitleBarColor = 'var(--theme-color-text-primary, #2c3e50)';
551
606
  let tmpDefaultBodyFill = '#ffffff';
552
607
  let tmpDefaultBodyStroke = '#d0d4d8';
553
608
  if (tmpNodeTypeConfig)
@@ -716,11 +771,23 @@ class PictViewFlowPropertiesPanel extends libPictView
716
771
  let tmpTetherService = this._FlowView._TetherService;
717
772
  if (!tmpTetherService) return;
718
773
 
719
- let tmpNodeData = this._FlowView.getNode(pPanelData.NodeHash);
720
- if (!tmpNodeData) return;
774
+ // A connection panel tethers to the edge midpoint; model it as a zero-size anchor at that
775
+ // point so the same tether geometry applies. A node panel tethers to its node.
776
+ let tmpAnchorData;
777
+ if (pPanelData.ConnectionHash)
778
+ {
779
+ let tmpMidpoint = this._FlowView.getConnectionMidpoint(pPanelData.ConnectionHash);
780
+ if (!tmpMidpoint) return;
781
+ tmpAnchorData = { X: tmpMidpoint.x, Y: tmpMidpoint.y, Width: 0, Height: 0 };
782
+ }
783
+ else
784
+ {
785
+ tmpAnchorData = this._FlowView.getNode(pPanelData.NodeHash);
786
+ if (!tmpAnchorData) return;
787
+ }
721
788
 
722
789
  let tmpViewIdentifier = this._FlowView.options.ViewIdentifier;
723
- tmpTetherService.renderTether(pPanelData, tmpNodeData, pTethersLayer, pIsSelected, tmpViewIdentifier);
790
+ tmpTetherService.renderTether(pPanelData, tmpAnchorData, pTethersLayer, pIsSelected, tmpViewIdentifier);
724
791
  }
725
792
 
726
793
  /**
@@ -1500,30 +1500,36 @@ class PictViewFlowToolbar extends libPictView
1500
1500
  */
1501
1501
  _buildSettingsPopup(pContainer)
1502
1502
  {
1503
- if (!this._FlowView || !this._FlowView._ThemeProvider) return;
1503
+ if (!this._FlowView) return;
1504
1504
 
1505
1505
  let tmpFlowViewIdentifier = this.options.FlowViewIdentifier;
1506
- let tmpThemeProvider = this._FlowView._ThemeProvider;
1507
- let tmpThemeKeys = tmpThemeProvider.getThemeKeys();
1508
- let tmpActiveKey = tmpThemeProvider.getActiveThemeKey();
1506
+ let tmpPresetsProvider = this._FlowView._StylePresetsProvider;
1507
+ let tmpRendererProvider = this._FlowView._RendererProvider;
1508
+ if (!tmpPresetsProvider || !tmpRendererProvider) return;
1509
+
1510
+ // The single "Style" picker surfaces curated presets — each one bundles
1511
+ // a ColorTheme + Renderer + EdgeTheme. Per-axis overrides live behind
1512
+ // future "Customize" UI; the toolbar shows the preset list only.
1513
+ let tmpPresets = tmpPresetsProvider.listPresets();
1514
+ let tmpActivePreset = tmpPresetsProvider.getActivePresetHash();
1509
1515
 
1510
1516
  let tmpThemeOptions = [];
1511
- for (let i = 0; i < tmpThemeKeys.length; i++)
1517
+ for (let i = 0; i < tmpPresets.length; i++)
1512
1518
  {
1513
- let tmpTheme = tmpThemeProvider._Themes[tmpThemeKeys[i]];
1519
+ let tmpPreset = tmpPresets[i];
1514
1520
  tmpThemeOptions.push(
1515
1521
  {
1516
- Value: tmpThemeKeys[i],
1517
- Label: tmpTheme.Label || tmpThemeKeys[i],
1518
- SelectedAttr: (tmpThemeKeys[i] === tmpActiveKey) ? ' selected="selected"' : ''
1522
+ Value: tmpPreset.Hash,
1523
+ Label: tmpPreset.Label || tmpPreset.Hash,
1524
+ SelectedAttr: (tmpPreset.Hash === tmpActivePreset) ? ' selected="selected"' : ''
1519
1525
  });
1520
1526
  }
1521
1527
 
1522
1528
  let tmpThemeOptionsHTML = this.pict.parseTemplateByHash('Flow-Layout-OptionList', { Options: tmpThemeOptions });
1523
1529
 
1524
- let tmpNoiseLevel = Math.round(tmpThemeProvider.getNoiseLevel() * 100);
1525
- let tmpActiveTheme = tmpThemeProvider.getActiveTheme();
1526
- let tmpNoiseEnabled = !!(tmpActiveTheme && tmpActiveTheme.NoiseConfig && tmpActiveTheme.NoiseConfig.Enabled);
1530
+ let tmpNoiseLevel = Math.round(tmpRendererProvider.getNoiseLevel() * 100);
1531
+ let tmpActiveRenderer = tmpRendererProvider.getActiveRenderer();
1532
+ let tmpNoiseEnabled = !!(tmpActiveRenderer && tmpActiveRenderer.NoiseConfig && tmpActiveRenderer.NoiseConfig.Enabled);
1527
1533
  let tmpNoiseDisplay = tmpNoiseEnabled ? '' : 'display:none;';
1528
1534
 
1529
1535
  this.pict.ContentAssignment.assignContent(pContainer,
@@ -1585,16 +1591,18 @@ class PictViewFlowToolbar extends libPictView
1585
1591
  let tmpNoiseSection = pContainer.querySelector('[data-settings-type="noise"]');
1586
1592
  if (!tmpNoiseSection) return;
1587
1593
 
1588
- let tmpTheme = this._FlowView._ThemeProvider.getActiveTheme();
1589
- if (tmpTheme && tmpTheme.NoiseConfig && tmpTheme.NoiseConfig.Enabled)
1594
+ let tmpRendererProvider = this._FlowView._RendererProvider;
1595
+ if (!tmpRendererProvider) { tmpNoiseSection.style.display = 'none'; return; }
1596
+ let tmpRenderer = tmpRendererProvider.getActiveRenderer();
1597
+ if (tmpRenderer && tmpRenderer.NoiseConfig && tmpRenderer.NoiseConfig.Enabled)
1590
1598
  {
1591
1599
  tmpNoiseSection.style.display = '';
1592
- // Update slider value to reflect theme default
1600
+ // Update slider value to reflect renderer default
1593
1601
  let tmpSlider = tmpNoiseSection.querySelector('.pict-flow-popup-settings-slider');
1594
1602
  let tmpValueLabel = tmpNoiseSection.querySelector('.pict-flow-popup-settings-slider-value');
1595
1603
  if (tmpSlider)
1596
1604
  {
1597
- let tmpLevel = Math.round(this._FlowView._ThemeProvider.getNoiseLevel() * 100);
1605
+ let tmpLevel = Math.round(tmpRendererProvider.getNoiseLevel() * 100);
1598
1606
  tmpSlider.value = String(tmpLevel);
1599
1607
  if (tmpValueLabel) tmpValueLabel.textContent = tmpLevel + '%';
1600
1608
  }